@ -1,6 +1,7 @@
import subprocess , json , psutil , time , os , win32security , sys , base64 , logging , ctypes , copy #Get input argument
import pickle
import inspect
import schedule
from partd import Server
from . import Server
@ -471,6 +472,38 @@ def OrchestratorLoggerGet():
"""
return GSettingsGet ( ) . get ( " Logger " , None )
def OrchestratorScheduleGet ( ) :
"""
Get the schedule ( schedule . readthedocs . io ) from the Orchestrator
Fro example you can use :
. . code - block : : python
# One schedule threaded
Orchestrator . OrchestratorScheduleGet ( ) . every ( 5 ) . seconds . do ( lProcess . StatusCheckStart )
#New schedule thread # See def description Orchestrator.OrchestratorThreadStart
Orchestrator . OrchestratorScheduleGet ( ) . every ( 5 ) . seconds . do ( Orchestrator . OrchestratorThreadStart , lProcess . StatusCheckStart )
: return : schedule module . Example see here https : / / schedule . readthedocs . io / en / stable / examples . html
"""
if GSettingsGet ( ) . get ( " SchedulerDict " , { } ) . get ( " Schedule " , None ) is None :
GSettingsGet ( ) [ " SchedulerDict " ] [ " Schedule " ] = schedule
return GSettingsGet ( ) . get ( " SchedulerDict " , { } ) . get ( " Schedule " , None )
def OrchestratorThreadStart ( inDef , * inArgList , * * inArgDict ) :
"""
Execute def in new thread and pass some args with list and dict types
: param inDef : Python Def
: param inArgList : args as list
: param inArgDict : args as dict
: return : threading . Thread object
"""
lDefThread = threading . Thread ( target = inDef , args = inArgList , kwargs = inArgDict )
lDefThread . start ( )
return lDefThread
def OrchestratorIsAdmin ( ) :
"""
Check if Orchestrator process is running as administrator
@ -2562,9 +2595,6 @@ def Orchestrator(inGSettings=None, inDumpRestoreBool = True, inRunAsAdministrato
ActivityItemDefAliasModulesLoad ( )
#Инициализация настроечных параметров
lDaemonLoopSeconds = gSettingsDict [ " SchedulerDict " ] [ " CheckIntervalSecFloat " ]
lDaemonActivityLogDict = { } #Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>)
lDaemonLastDateTime = datetime . datetime . now ( )
gSettingsDict [ " ServerDict " ] [ " WorkingDirectoryPathStr " ] = os . getcwd ( ) # Set working directory in g settings
#Инициализация сервера (инициализация всех интерфейсов)
@ -2615,69 +2645,97 @@ def Orchestrator(inGSettings=None, inDumpRestoreBool = True, inRunAsAdministrato
lProcessorMonitorThread . start ( ) # Start the thread execution.
if lL : lL . info ( " Processor monitor has been started " ) #Logging
if lL : lL . info ( " Scheduler loop start " ) #Logging
gDaemonActivityLogDictRefreshSecInt = 10 # The second period for clear lDaemonActivityLogDict from old items
gDaemonActivityLogDictLastTime = time . time ( ) # The second perioad for clean lDaemonActivityLogDict from old items
while True :
try :
lCurrentDateTime = datetime . datetime . now ( )
#Циклический обход правил
lFlagSearchActivityType = True
# Periodically clear the lDaemonActivityLogDict
if time . time ( ) - gDaemonActivityLogDictLastTime > = gDaemonActivityLogDictRefreshSecInt :
gDaemonActivityLogDictLastTime = time . time ( ) # Update the time
for lIndex , lItem in enumerate ( lDaemonActivityLogDict ) :
if lItem [ " ActivityEndDateTime " ] and lCurrentDateTime < = lItem [ " ActivityEndDateTime " ] :
pass
# Activity is actual - do not delete now
else :
# remove the activity - not actual
lDaemonActivityLogDict . pop ( lIndex , None )
lIterationLastDateTime = lDaemonLastDateTime # Get current datetime before iterator (need for iterate all activities in loop)
# Iterate throught the activity list
for lIndex , lItem in enumerate ( gSettingsDict [ " SchedulerDict " ] [ " ActivityTimeList " ] ) :
try :
# Prepare GUID of the activity
lGUID = None
if " GUID " in lItem and lItem [ " GUID " ] :
lGUID = lItem [ " GUID " ]
else :
lGUID = str ( uuid . uuid4 ( ) )
lItem [ " GUID " ] = lGUID
#Проверка дней недели, в рамках которых можно запускать активность
lItemWeekdayList = lItem . get ( " WeekdayList " , [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ] )
if lCurrentDateTime . weekday ( ) in lItemWeekdayList :
if lFlagSearchActivityType :
#######################################################################
#Branch 1 - if has TimeHH:MM
#######################################################################
if " TimeHH:MMStr " in lItem :
#Вид активности - запуск процесса
#Сформировать временной штамп, относительно которого надо будет проверять время
#часовой пояс пока не учитываем
lActivityDateTime = datetime . datetime . strptime ( lItem [ " TimeHH:MMStr " ] , " % H: % M " )
lActivityDateTime = lActivityDateTime . replace ( year = lCurrentDateTime . year , month = lCurrentDateTime . month , day = lCurrentDateTime . day )
#Убедиться в том, что время наступило
if (
lActivityDateTime > = lDaemonLastDateTime and
lCurrentDateTime > = lActivityDateTime ) :
# Log info about activity
if lL : lL . info ( f " Scheduler:: Activity list is started in new thread. Parameters are not available to see. " ) #Logging
# Do the activity
lThread = threading . Thread ( target = Processor . ActivityListExecute , kwargs = { " inGSettings " : inGSettings , " inActivityList " : lItem [ " ActivityList " ] } )
lThread . start ( )
lIterationLastDateTime = datetime . datetime . now ( ) # Set the new datetime for the new processor activity
except Exception as e :
if lL : lL . exception ( f " Scheduler: Exception has been catched in Scheduler module when activity time item was initialising. ActivityTimeItem is { lItem } " )
lDaemonLastDateTime = lIterationLastDateTime # Set the new datetime for the new processor activity
#Уснуть до следующего прогона
time . sleep ( lDaemonLoopSeconds )
except Exception as e :
if lL : lL . exception ( f " Scheduler: Exception has been catched in Scheduler module. Global error " )
# Scheduler loop
lSchedulerThread = threading . Thread ( target = __deprecated_orchestrator_loop__ )
lSchedulerThread . daemon = True # Run the thread in daemon mode.
lSchedulerThread . start ( ) # Start the thread execution.
if lL : lL . info ( " Scheduler (old) loop start " ) #Logging
# Schedule (new) loop
lScheduleThread = threading . Thread ( target = __schedule_loop__ )
lScheduleThread . daemon = True # Run the thread in daemon mode.
lScheduleThread . start ( ) # Start the thread execution.
if lL : lL . info ( " Schedule module (new) loop start " ) #Logging
def __schedule_loop__ ( ) :
while True :
schedule . run_pending ( )
time . sleep ( 3 )
# Backward compatibility below to 1.2.7
def __deprecated_orchestrator_loop__ ( ) :
lL = OrchestratorLoggerGet ( )
inGSettings = GSettingsGet ( )
lDaemonLoopSeconds = gSettingsDict [ " SchedulerDict " ] [ " CheckIntervalSecFloat " ]
lDaemonActivityLogDict = { } # Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>)
lDaemonLastDateTime = datetime . datetime . now ( )
gDaemonActivityLogDictRefreshSecInt = 10 # The second period for clear lDaemonActivityLogDict from old items
gDaemonActivityLogDictLastTime = time . time ( ) # The second perioad for clean lDaemonActivityLogDict from old items
while True :
try :
lCurrentDateTime = datetime . datetime . now ( )
# Циклический обход правил
lFlagSearchActivityType = True
# Periodically clear the lDaemonActivityLogDict
if time . time ( ) - gDaemonActivityLogDictLastTime > = gDaemonActivityLogDictRefreshSecInt :
gDaemonActivityLogDictLastTime = time . time ( ) # Update the time
for lIndex , lItem in enumerate ( lDaemonActivityLogDict ) :
if lItem [ " ActivityEndDateTime " ] and lCurrentDateTime < = lItem [ " ActivityEndDateTime " ] :
pass
# Activity is actual - do not delete now
else :
# remove the activity - not actual
lDaemonActivityLogDict . pop ( lIndex , None )
lIterationLastDateTime = lDaemonLastDateTime # Get current datetime before iterator (need for iterate all activities in loop)
# Iterate throught the activity list
for lIndex , lItem in enumerate ( gSettingsDict [ " SchedulerDict " ] [ " ActivityTimeList " ] ) :
try :
# Prepare GUID of the activity
lGUID = None
if " GUID " in lItem and lItem [ " GUID " ] :
lGUID = lItem [ " GUID " ]
else :
lGUID = str ( uuid . uuid4 ( ) )
lItem [ " GUID " ] = lGUID
# Проверка дней недели, в рамках которых можно запускать активность
lItemWeekdayList = lItem . get ( " WeekdayList " , [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ] )
if lCurrentDateTime . weekday ( ) in lItemWeekdayList :
if lFlagSearchActivityType :
#######################################################################
# Branch 1 - if has TimeHH:MM
#######################################################################
if " TimeHH:MMStr " in lItem :
# Вид активности - запуск процесса
# Сформировать временной штамп, относительно которого надо будет проверять время
# часовой пояс пока не учитываем
lActivityDateTime = datetime . datetime . strptime ( lItem [ " TimeHH:MMStr " ] , " % H: % M " )
lActivityDateTime = lActivityDateTime . replace ( year = lCurrentDateTime . year ,
month = lCurrentDateTime . month ,
day = lCurrentDateTime . day )
# Убедиться в том, что время наступило
if (
lActivityDateTime > = lDaemonLastDateTime and
lCurrentDateTime > = lActivityDateTime ) :
# Log info about activity
if lL : lL . info (
f " Scheduler:: Activity list is started in new thread. Parameters are not available to see. " ) # Logging
# Do the activity
lThread = threading . Thread ( target = Processor . ActivityListExecute ,
kwargs = { " inGSettings " : inGSettings ,
" inActivityList " : lItem [ " ActivityList " ] } )
lThread . start ( )
lIterationLastDateTime = datetime . datetime . now ( ) # Set the new datetime for the new processor activity
except Exception as e :
if lL : lL . exception (
f " Scheduler: Exception has been catched in Scheduler module when activity time item was initialising. ActivityTimeItem is { lItem } " )
lDaemonLastDateTime = lIterationLastDateTime # Set the new datetime for the new processor activity
# Уснуть до следующего прогона
time . sleep ( lDaemonLoopSeconds )
except Exception as e :
if lL : lL . exception ( f " Scheduler: Exception has been catched in Scheduler module. Global error " )
# Backward compatibility below to 1.2.0
def __deprecated_orchestrator_start__ ( ) :