From 18ae510488f32076a2937ecab83de0bd1eaeb4e0 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Wed, 15 May 2019 23:35:44 +0300 Subject: [PATCH] #Orchestrator_NewFunction_ActivityLoop --- Orchestrator/orchestratorConfiguration.json | 11 ++++ Orchestrator/orchestratorMain.py | 25 +++++++- Orchestrator/orchestratorTimer.py | 65 +++++++++++++++++++++ 3 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 Orchestrator/orchestratorTimer.py diff --git a/Orchestrator/orchestratorConfiguration.json b/Orchestrator/orchestratorConfiguration.json index 11ce19ea..7b19a57e 100644 --- a/Orchestrator/orchestratorConfiguration.json +++ b/Orchestrator/orchestratorConfiguration.json @@ -51,7 +51,18 @@ "flagCloseForce":true, "_flagCloseOnlyCurrentUser":"Признак, что процесс нужно закрыть только у текущего пользователя", "flagCloseOnlyCurrentUser":true + }, + { + "activityType":"loopActivity", + "loopSeconds":4, + "loopTimeStart":"23:34", + "loopTimeEnd":"23:35", + "pythonPackageName":"", + "pythonFunctionName":"", + "processPath":"notepad", + "processArgs":"" } ] + } \ No newline at end of file diff --git a/Orchestrator/orchestratorMain.py b/Orchestrator/orchestratorMain.py index ceba7b4b..b84c72e0 100644 --- a/Orchestrator/orchestratorMain.py +++ b/Orchestrator/orchestratorMain.py @@ -7,6 +7,8 @@ import os import signal import pdb import orchestratorServer +import orchestratorTimer + lGlobalDict={} #"JSONConfigurationDict": #"ActivityLog":[{""}] @@ -56,7 +58,7 @@ while True: lCurrentDateTime>=lActivityDateTime and (lItem["activityType"],lActivityDateTime,lItem["processPath"]) not in lDaemonActivityLogDict): #Выполнить операцию - print("ProcessStart:"+lItem["processPath"]) + print(datetime.datetime.now().isoformat()+":: ProcessStart:"+lItem["processPath"]) #Запись в массив отработанных активностей lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processPath"])]={"ActivityStartDateTime":lCurrentDateTime} #Лог @@ -91,7 +93,26 @@ while True: lGlobalDict["ActivityLogScheduleList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processPath"], "activityStartDateTime":str(lCurrentDateTime)}) #Завершить процесс os.system(lActivityCloseCommand) - print("ProcessStop "+lItem["processName"]) + print(datetime.datetime.now().isoformat()+":: ProcessStop "+lItem["processName"]) + #Вид активности - запуск отдельного потока с циклическим вызовом + if lItem["activityType"]=="loopActivity": + #Сформировать временной штамп, относительно которого надо будет проверять время + #часовой пояс пока не учитываем + lActivityDateTime=datetime.datetime.strptime(lItem["loopTimeStart"],"%H:%M") + lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day) + #Убедиться в том, что время наступило + if ( + lActivityDateTime>=lDaemonStartDateTime and + lCurrentDateTime>=lActivityDateTime and + (lItem["activityType"],lActivityDateTime,lItem["processPath"]) not in lDaemonActivityLogDict): + #Запись в массив отработанных активностей + lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processPath"])]={"ActivityStartDateTime":lCurrentDateTime} + lActivityTimeEndDateTime=datetime.datetime.strptime(lItem["loopTimeEnd"],"%H:%M") + lActivityTimeEndDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day) + #Лог + lGlobalDict["ActivityLogScheduleList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processPath"], "activityStartDateTime":str(lCurrentDateTime)}) + #Запуск циклической процедуры + orchestratorTimer.activityLoopStart(1,lItem["processPath"],lItem["processArgs"],lActivityTimeEndDateTime,lItem["pythonPackageName"],lItem["pythonFunctionName"]) #Уснуть до следующего прогона time.sleep(lDaemonLoopSeconds) diff --git a/Orchestrator/orchestratorTimer.py b/Orchestrator/orchestratorTimer.py new file mode 100644 index 00000000..e7164c23 --- /dev/null +++ b/Orchestrator/orchestratorTimer.py @@ -0,0 +1,65 @@ +from threading import Timer +import datetime +import subprocess +import importlib +class RepeatedTimer(object): + def __init__(self, interval, function, *args, **kwargs): + self._timer = None + self.interval = interval + self.function = function + self.args = args + self.kwargs = kwargs + self.is_running = False + self.start() + def _run(self): + self.is_running = False + lResult = self.function(*self.args, **self.kwargs) + if lResult is not None: + if lResult: + self.start() + def start(self): + if not self.is_running: + self._timer = Timer(self.interval, self._run) + self._timer.start() + self.is_running = True + + def stop(self): + self._timer.cancel() + self.is_running = False + +############################################################ +####Техническая функция обработки таймера - потока +############################################################ +def activityLoopExecution(inProcessPath,inProcessArgList,inLoopTimeEndDateTime,inPythonPackageName,inPythonFunctionName): + lResultGoLoop=True + lCurrentDateTime=datetime.datetime.now() + print (datetime.datetime.now().isoformat()+":: Loop activity check") + #Запустить процесс, если установлен inProcessPath + if inProcessPath is not None: + if inProcessPath != "": + lItemArgs=[inProcessPath] + lItemArgs.extend(inProcessArgList) + subprocess.Popen(lItemArgs,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) + + #Импорт Python пакета и запуск функции из него + if inPythonPackageName is not None: + if inPythonPackageName != "": + try: + #Подключить модуль для вызова + lModule=importlib.import_module(inPythonPackageName) + #Найти функцию + lFunction=getattr(lModule,inPythonFunctionName) + except Exception as e: + print (datetime.datetime.now().isoformat()+":: Loop activity error: module/function not founded") + + #Выключить таймер, если время наступило + if lCurrentDateTime>=inLoopTimeEndDateTime: + lResultGoLoop=False + #Вернуть результат + return lResultGoLoop +############################################################ +####Функция запуска таймера - потока +############################################################ +def activityLoopStart(inActivityLoopSeconds,inProcessPath,inProcessArgList,inLoopTimeEndDateTime,inPythonPackageName,inPythonFunctionName): + lTimer = RepeatedTimer(inActivityLoopSeconds, activityLoopExecution, inProcessPath,inProcessArgList,inLoopTimeEndDateTime,inPythonPackageName,inPythonFunctionName) # it auto-starts, no need of rt.start() + lTimer.start()