KNOWLEDGE BASE
Log In    |    Knowledge Base    |    4D Home
Tech Tip: A utility that facilitates a clean shutdown on server, client and standalone
PRODUCT: 4D | VERSION: v13.x, v14.x, v15.x | PLATFORM: Mac & Win
Published On: December 8, 2016

One of the chores in executing a clean shutdown of a 4D application is the termination of all live user process once QUIT 4D is called. When QUIT 4D is called, from menu or method, 4D will call the On exit database method. From this method the developer is given the opportunity to gracefully terminate any live user processes.

If live user processes are not terminated from the On exit database method or the On Server Shutdown database method, any code expected to run as a processes terminates, such as writing to a log file, does not get executed because the process simple gets aborted by 4D.

The utility below, WakeUpProcesses, is intended to run from one of the database methods mentioned above and calls all live user processes, giving each live user process the opportunity to terminate gracefully.

Because there is no guarantee that over the life of a run of a database that the current number of "live" processes will be numbered sequentially, depending on the value returned by the commands Count tasks or Count user processes as how many times to execute a loop is false security.

The methodology in this utility is to use a loop set to run a number of times that is greater than the number of processes that would be expected to be created over the life of the run. In this case the value MAXINT is chosen. However, the loop will not run that many times. Instead, the loop will be terminated when the number of processes tested match the value return by the command Count tasks.

If (True)
    If (False)
       Begin SQL
       /*
          Name: WakeUpProcesses
          Path: WakeUpProcesses
   
          Purpose: Wakeup user processes for clean termination before shutdown
   
       */
       End SQL
    End if
    C_TEXT($MethodName_T)
    $MethodName_T:=Current method name
    //===================== Declare Variables ==================================
    //method_parameters_declarations
    //--------------------------------------------------------------------------
    //method_wide_constants_declarations
    //--------------------------------------------------------------------------
    //local_variable_declarations
    C_LONGINT($Params_L;$maxProcId_l;$countTask_l;$procNum_l;\
       $procState_l;$procUniqueID_l;$procOrigin_l)
    C_TEXT($procName_t)
    C_TIME($procTime_h)
    C_BOOLEAN($procVisible_b)
   
End if
   //====================== Initialize and Setup ================================

$Params_L:=Count parameters

   // "Count tasks" returns the total number of processes open,
   // not necessarily the highest process number for a given process, so
   // MAXINT is used as a number that can be reasonablly assumed greater
   // than any number of processes that would have been opened since startup
   //
$maxProcId_l:=MAXINT
$countTask_l:=0

   //======================== Method Actions ==================================

For ($procNum_l;1;$maxProcId_l)
    PROCESS PROPERTIES($procNum_l;$procName_t;$procState_l;\
    $procTime_h;$procVisible_b;$procUniqueID_l;$procOrigin_l)
    If ($procState_l>=Aborted) // *** Process is recongnized by 4D even if it is marked as aborted
   
    // *** If the process is running and it is a user process.
       If ($procOrigin_l>=None)
          Case of
             : ($procState_l=Paused)
                RESUME PROCESS($procNum_l)
             : ($procState_l=Delayed)
                DELAY PROCESS($procNum_l;0)
          End case
   
       End if
       $countTask_l:=$countTask_l+1
    End if
   
    If ($countTask_l>=Count tasks) // *** Found all opened processes
       $procNum_l:=$maxProcId_l+1 // *** Time to get out of the loop
    End if
End for


Commented by Kirk Brooks on January 14, 2019 at 4:50 PM
In the code above the following change : : ($procState_l=Delayed) DELAY PROCESS($procNum_l;0) to this: : ($procState_l=Delayed) RESUME PROCESS($procNum_l) Otherwise it takes a long time for 4D to actually quit.