4D v16.3

On Exit database method

Home

 
4D v16.3
On Exit database method

On Exit database method 


 

On Exit database method  
Does not require any parameters

  

The On Exit database method is called once when you quit a database.

This method is used in the following 4D environments:

  • 4D in local mode
  • 4D in remote mode
  • 4D application compiled and merged with 4D VolumeDesktop

Note: The On Exit database method is NOT invoked by 4D Server.

The On Exit database method is automatically invoked by 4D; unlike project methods, you cannot call this database method yourself by programming. You can however execute it from the Method editor. You can also use subroutines.

A database can be exited if any of the following occur:

  • The user selects the menu command Quit from the Design Environment File menu or from the Application environment (Quit standard action)
  • A call to the QUIT 4D command is issued
  • A 4D Plug-in issues a call to the QUIT 4D entry point

No matter how the exit from the database was initiated, 4D performs the following actions:

  • If there is no On Exit database method, 4D aborts each running process one by one, without distinction. If the user is performing data entry, the records will be cancelled and not saved.
  • If there is an On Exit database method, 4D starts executing this method within a newly created local process. Note that 4D will eventually quit—the On Exit database method can perform all the cleanup or closing operations you want, but it cannot refuse the quit, and will at some point end.

The On Exit database method is the perfect place to:

  • Save (locally, on disk) Preferences or Settings to be reused at the beginning of the next session in the On Startup database method
  • Perform any other actions that you want to be done automatically each time a database is exited

Note: Don’t forget that the On Exit database method is a local/client process, so it cannot access the data file. Thus, if the On Exit database method performs a query or a sort, a 4D Client that is about to quit will "freeze" and actually will not quit. If you need to access data when a client quits the application, create a new global process from within the On Exit database method, which will be able to access the data file. In this case, be sure that the new process will terminate correctly before the end of the On Exit database method execution (by using interprocess variables, by example).

Note: In a client/server environment, the On Exit database method behaves differently depending on whether the user quits manually (through the Quit menu command or a call to the QUIT 4D command) or 4D Server is shutdown, which forces all clients to quit.
When 4D Server shuts down and provides a cutoff time (e.g. 10 minutes), each connected client displays a warning message and if the user quits during the given time frame, the On Exit database method is executed normally. However, in other cases (e.g. the user does not respond in time, the server requests to quit immediately, or the client is manually disconnected by the Administrator), the On Exit database method is executed at the same time that the connection to the server is closed. As a result, the code in the On Exit database method can't launch another local or server process, and can't wait for other processes to be cancelled (nor can these processes continue to access the server). If it tries to do so, a network error is generated (such as 10001 or 10002) since the connection to the server is already closed.

To properly stop running processes in the case of unexpected shut downs, you must test the Process aborted command in every loop (for, while, repeat) which may run longer than one second. Process aborted returns true if 4D (local, remote or 4D Server) is about to quit, meaning that processing is about to stop immediately. In this case, cancel any processing (CANCEL TRANSACTION, etc.) and quit as quickly as possible. Although you have time if the user manually quits, you do not have time if the application is forced to quit.

Example  

The following example covers all the methods used in a database that tracks the significant events that occur during a working session and writes a description in a text document called “Journal.”

  • The On Startup database method initializes the interprocess variable ◊vbQuit4D, which tells all the use processes whether or not the database is being exited. It also creates the journal file, if it does not already exist.
  ` On Startup Database Method
 C_TEXT(◊vtIPMessage)
 C_BOOLEAN(◊vbQuit4D)
 ◊vbQuit4D:=False
 
 If(Test path name("Journal")#Is a document)
    $vhDocRef:=Create document("Journal")
    If(OK=1)
       CLOSE DOCUMENT($vhDocRef)
    End if
 End if
 WRITE JOURNAL("Opening Session")

  • The project method WRITE JOURNAL, used as subroutine by the other methods, writes the information it receives, in the journal file:
  ` WRITE JOURNAL Project Method
  ` WRITE JOURNAL ( Text )
  ` WRITE JOURNAL ( Event description )
 C_TEXT($1)
 C_TIME($vhDocRef)
 
 While(Semaphore("$Journal"))
    DELAY PROCESS(Current process;1)
 End while
 $vhDocRef:=Append document("Journal")
 If(OK=1)
    PROCESS PROPERTIES(Current process;$vsProcessName;$vlState;$vlElapsedTime;$vbVisible)
    SEND PACKET($vhDocRef;String(Current date)+Char(9)+String(Current time)+Char(9)
    +String(Current process)+Char(9)+$vsProcessName+Char(9)+$1+Char(13))
    CLOSE DOCUMENT($vhDocRef)
 End if
 CLEAR SEMAPHORE("$Journal")

Note that the document is open and closed each time. Also note the use of a semaphore as “access protection” to the document—we do not want two processes trying to access the journal file at the same time.

  • The M_ADD_RECORDS project method is executed when a menu item Add Record is chosen in the Application environment:
  ` M_ADD_RECORDS Project Method
 SET MENU BAR(1)
 Repeat
    ADD RECORD([Table1];*)
    If(OK=1)
       WRITE JOURNAL("Adding record #"+String(Record number([Table1]))+" in Table1")
    End if
 Until((OK=0)|◊vbQuit4D)

This method loops until the user cancels the last data entry or exits the database.

  • The input form for [Table 1] includes the treatment of the On Outside Call events. So, even if a process is in data entry, it can be exited smoothly, with the user either saving (or not saving) the current data entry:
  ` [Table1];"Input" Form Method
 Case of
    :(Form event=On Outside Call)
       If(◊vtIPMessage="QUIT")
          CONFIRM("Do you want to save the changes made to this record?")
          If(OK=1)
             ACCEPT
          Else
             CANCEL
          End if
       End if
 End case

  • The M_QUIT project method is executed when Quit is chosen from the File menu in the Application environment:
  ` M_QUIT Project Method
 $vlProcessID:=New process("DO_QUIT";32*1024;"$DO_QUIT")

The method uses a trick. When QUIT 4D is called, the command has an immediate effect. Therefore, the process from which the call is issued is in “stop mode” until the database is actually exited. Since this process can be one of the processes in which data entry occurs, the call to QUIT 4D is made in a local process that is started only for this purpose. Here is the DO_QUIT method:

  ` DO_QUIT Project Method
 CONFIRM("Are you sure you want to quit?")
 If(OK=1)
    WRITE JOURNAL("Quitting Database")
    QUIT 4D
  ` QUIT 4D has an immediate effect, any line of code below will never be executed
  ` ...
 End if

  • Finally, here is the On Exit database method which tells all open user processes “It's time to get out of here!” It sets ◊vbQuit4D to True and sends interprocess messages to the user processes that are performing data entry:
  ` On Exit Database Method
 ◊vbQuit4D:=True
 Repeat
    $vbDone:=True
    For($vlProcess;1;Count tasks)
       PROCESS PROPERTIES($vlProcess;$vsProcessName;$vlState;$vlElapsedTime;$vbVisible)
       If(((($vsProcessName="ML_@")|($vsProcessName="M_@")))&($vlState>=0))
          $vbDone:=False
          ◊vtIPMessage:="QUIT"
          BRING TO FRONT($vlProcess)
          CALL PROCESS($vlProcess)
          $vhStart:=Current time
          Repeat
             DELAY PROCESS(Current process;60)
          Until((Process state($vlProcess)<0)|((Current time-$vhStart)>=?00:01:00?))
       End if
    End for
 Until($vbDone)
 WRITE JOURNAL("Closing session")

Note: Processes that have names beginning with "ML_..." or "M_..." are started by menu commands for which the Start a New Process property has been selected. In this example, these are the processes started when the menu command Add record was chosen.

The test (Current time-$vhStart)>=?00:01:00? allows the database method to get out of the “waiting the other process” Repeat loop if the other process does not act immediately.

The following is a typical example of the Journal file produced by the database:
2/6/0315:47:251Main processOpening Session
2/6/0315:55:435ML_1Adding record #23 in Table1
2/6/0315:55:465ML_1Adding record #24 in Table1
2/6/0315:55:546$DO_QUITQuitting Database
2/6/0315:55:587$xxClosing session

Note: The name $xx is the name of the local process started by 4D in order to execute the On Exit database method.



See also 

On Startup database method
QUIT 4D

 
PROPERTIES 

Product: 4D
Theme: Database Methods

 
HISTORY 

Created:

 
ARTICLE USAGE

4D Language Reference ( 4D v16)
4D Language Reference ( 4D v16.1)
4D Language Reference ( 4D v16.2)
4D Language Reference ( 4D v16.3)