project BLF > class BBaseDaemon > method ControlDaemon
Description
This method should be called whenever a daemon-process is started (run of a daemon), stopped or a request to stop has been received.
This method should only be called from the daemon processor components and has a transaction on its own.
Parameters
iiDaemonId | input | integer | Daemon Id of the daemon that needs to be "controlled". |
icStatus | input | character | The status to which the daemon should be switched. |
ocErrorMessage | output | character | The error message that is produced in case of an error. |
iiProcessId | input | integer | |
icDaemonHostname | input | character | |
oiReturnStatus | output | integer | Return status of the method. |
Internal usage
BLF
program code (program1/bbasedaemon.p)
OLCloop: repeat:
/* ================== */
/* Validate daemon id */
/* ================== */
if iiDaemonID = 0 or
iiDaemonID = ?
then do :
assign oiReturnStatus = -3.
<M-1 run SetMessage
(input #T-82'Update the daemon. The daemon ID is mandatory.':255(60)T-82# (icMessage),
input '' (icArguments),
input '' (icFieldName),
input '' (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '' (icRowid),
input 'BLF-17':U (icFcMsgNumber),
input '' (icFcExplanation),
input '' (icFcIdentification),
input '' (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BBaseDaemon>
Return.
end. /* if iiDaemonID = 0 or */
/* ====================================================================================================== */
/* Start from an emtpy instance to make sure we are not working with old information// then Load the data */
/* ====================================================================================================== */
<M-2 run ClearData (output viFcReturnSuper (oiReturnStatus)) in BBaseDaemon>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then do:
assign ocErrorMessage = trim(substitute(#T-12'Update the daemon; unable clear the current instance information. Daemon ID; &1':255(61)T-12#,string(iiDaemonID))).
return.
end.
<M-3 run DataLoad
(input ? (icRowids),
input iiDaemonId (icPkeys),
input ? (icObjectIds),
input '' (icFreeform),
input false (ilKeepPrevious),
output viFcReturnSuper (oiReturnStatus)) in BBaseDaemon>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then do:
assign ocErrorMessage = trim(substitute(#T-17'Update the daemon; unable to load it based on its ID (&1).':255(62)T-17#,string(iiDaemonID))).
return.
end.
find first tfcDaemon where tfcDaemon.DaemonID = iiDaemonID.
/* ============================================================= */
/* Skip if the status = Inactive and the new status is stopping */
/* ============================================================= */
if icStatus = {&DAEMONSTATUS-STOPPING} and
tfcDaemon.DaemonStatus = {&DAEMONSTATUS-INACTIVE}
then return.
/* =============== */
/* Update the data */
/* =============== */
case icStatus :
when {&DAEMONSTATUS-RUNNING}
then do:
/* Save date and time in UTC */
session:timezone = 0.
assign tfcDaemon.DaemonRunningProcesses = (if tfcDaemon.DaemonStatus = {&DAEMONSTATUS-RUNNING}
then tfcDaemon.DaemonRunningProcesses + 1
else 1)
tfcDaemon.DaemonStatus = icStatus
tfcDaemon.DaemonLastStartDate = today
tfcDaemon.DaemonLastStartTime = time
tfcDaemon.tc_Status = "C":U.
session:timezone = viTimeOffset.
if tfcDaemon.DaemonRunningProcesses = 1
then tfcDaemon.DaemonProcessIDs = (if icDaemonHostname = "" then "" else icDaemonHostname + ":") + string(iiProcessId).
else if icDaemonHostname = ""
then tfcDaemon.DaemonProcessIDs = trim(tfcDaemon.DaemonProcessIDs + "," + string(iiProcessId),",").
else ADDPID: do:
do viFcCount3 = 1 to num-entries(tfcDaemon.DaemonProcessIDs):
if entry (1,entry(viFcCount3,tfcDaemon.DaemonProcessIDs),":") = icDaemonHostname
then do:
entry(viFcCount3,tfcDaemon.DaemonProcessIDs) = entry(viFcCount3,tfcDaemon.DaemonProcessIDs) + "," + string(iiProcessId).
leave ADDPID.
end.
end.
tfcDaemon.DaemonProcessIDs = trim(tfcDaemon.DaemonProcessIDs + "," + icDaemonHostname + ":" + string(iiProcessId),",").
end.
end.
when {&DAEMONSTATUS-STOPPING}
then do :
assign tfcDaemon.DaemonStatus = icStatus
tfcDaemon.tc_Status = "C":U.
/* ============================================================================================== */
/* Set the LastUser on the daemon - this has to be done here and not in the actual daemon-process */
/* as the current user there is the user that is specified in the daemon-configuration while here */
/* we need to know the user who started/stopped the daemon. */
/* Here we set the user who last stopped the daemon but do note that the user who last started */
/* the daemon is set in TDaemonUtility:StartDaemon() */
/* ============================================================================================== */
assign tfcDaemon.LastStoppedUsr_ID = viUsrId. /* Set the user who stopped the daemon here when marking the status as 'Stopping' as when marking it as 'Inactive' is done by the daemon-itself. And here we want to track the person who requested the dmn to go down */
end.
when {&DAEMONSTATUS-INACTIVE} then do:
/* Save date and time in UTC */
session:timezone = 0.
assign tfcDaemon.DaemonStatus = (if tfcDaemon.DaemonRunningProcesses > 1 and iiProcessId <> 0
then tfcDaemon.DaemonStatus
else icStatus)
tfcDaemon.DaemonRunningProcesses = (if tfcDaemon.DaemonRunningProcesses > 1 and iiProcessId <> 0
then tfcDaemon.DaemonRunningProcesses - 1
else 0)
tfcDaemon.DaemonLastEndDate = today
tfcDaemon.DaemonLastEndTime = time
tfcDaemon.tc_Status = "C":U.
session:timezone = viTimeOffset.
if tfcDaemon.DaemonRunningProcesses = 0
then tfcDaemon.DaemonProcessIDs = "".
else do:
vcProcessHostname = icDaemonHostname.
do viFcCount3 = 1 to num-entries(tfcDaemon.DaemonProcessIDs):
if num-entries (entry(viFcCount3,tfcDaemon.DaemonProcessIDs),":") = 2
then do:
vcProcessHostname = entry (1,entry(viFcCount3,tfcDaemon.DaemonProcessIDs),":").
if (icDaemonHostname = vcProcessHostname or icDaemonHostname = "")
and entry (2,entry(viFcCount3,tfcDaemon.DaemonProcessIDs),":") = string(iiProcessId)
then do:
entry(viFcCount3,tfcDaemon.DaemonProcessIDs) = "".
leave.
end.
end.
else if (icDaemonHostname = vcProcessHostname or icDaemonHostname = "")
and entry(viFcCount3,tfcDaemon.DaemonProcessIDs) = string(iiProcessId)
then do:
entry(viFcCount3,tfcDaemon.DaemonProcessIDs) = "".
leave.
end.
end.
tfcDaemon.DaemonProcessIDs = trim(replace(tfcDaemon.DaemonProcessIDs,",,",","),",").
end.
end.
end case.
/* ================================================================= */
/* Setting the daemon status does not require validation. */
/* ================================================================= */
vlFcDataValidated = yes.
<M-7 run AdditionalUpdates (output viFcReturnSuper (oiReturnStatus)) in BBaseDaemon>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then do:
assign ocErrorMessage = trim(substitute(#T-28'An error has occurred on &1 (daemon ID = &3), error number = &2.':255(64)T-28#,"AdditionalUpdates":U,string(oiReturnStatus),string(iiDaemonID))).
return.
end.
<M-9 run DataSave (output viFcReturnSuper (oiReturnStatus)) in BBaseDaemon>
/* Repeat everything in case an optimistic lock error occured. */
if viFcReturnSuper = -2
then do:
viOLCount = viOLCount + 1.
if viOLCount < 6
then do:
oiReturnStatus = 0.
<M-38 run ClearMessages (output viFcReturnSuper (oiReturnStatus)) in BBaseDaemon>
next OLCloop.
end.
end.
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then do:
assign ocErrorMessage = trim(substitute(#T-33'An error has occurred on &1 (daemon ID = &3), error number = &2.':255(64)T-33#,"DataSave":U,string(oiReturnStatus),string(iiDaemonID))).
return.
end.
leave OLCloop.
end.
finally:
for each tFcMessages:
assign ocErrorMessage = ocErrorMessage + chr(10) +
(if tFcMessages.tcFcType = "W":U then trim(#T-34'Warning':100(38)t-34#) + "; ":U else trim(#T-35'Error':100(39)t-35#) + "; ":U) +
(if tFcMessages.tcFcMessage = ? then "?":U else tFcMessages.tcFcMessage) +
(if tFcMessages.tcFcFieldName = ? then "":U else " ":U + trim(#T-36'Field Name':100(40)T-36#) + "; ":U + tFcMessages.tcFcFieldName) +
(if tFcMessages.tcFcFieldValue = ? then "":U else " ":U + trim(#T-37'Field Value':100(41)T-37#) + "; ":U + tFcMessages.tcFcFieldValue).
end.
end finally.