Fix Managers.Process add timeout to status check

merge-requests/1/merge
robo-bo 2 years ago
parent d15cec2277
commit 77c27f526b

@ -393,7 +393,7 @@ class Process():
lL.info(f"Модуль Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Состояние процесса изменилось на {self.mStatusStr})") lL.info(f"Модуль Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Состояние процесса изменилось на {self.mStatusStr})")
def StatusCheck(self): def StatusCheck(self, inTimeoutSecFloat=9.0):
""" """
Check if process is alive. The def will save the manual flag is exists. Don't wait mute but set mute if it is not set. Check if process is alive. The def will save the manual flag is exists. Don't wait mute but set mute if it is not set.
@ -405,7 +405,8 @@ class Process():
#self.MuteWait() #self.MuteWait()
self.mAgentMuteBool=True self.mAgentMuteBool=True
lGUIDStr = __Orchestrator__.AgentActivityItemAdd(inHostNameStr=self.mAgentHostNameStr,inUserStr=self.mAgentUserNameStr,inActivityItemDict=lActivityItemUserProcessList) lGUIDStr = __Orchestrator__.AgentActivityItemAdd(inHostNameStr=self.mAgentHostNameStr,inUserStr=self.mAgentUserNameStr,inActivityItemDict=lActivityItemUserProcessList)
lUserProcessList = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lGUIDStr) try:
lUserProcessList = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lGUIDStr,inTimeoutSecFloat=inTimeoutSecFloat)
if self.mProcessNameWOExeStr.upper() in lUserProcessList: if self.mProcessNameWOExeStr.upper() in lUserProcessList:
if self.mStatusStr == "1_STOPPED_MANUAL": self.mStatusStr = "5_STARTED_MANUAL"; lLogBool=True if self.mStatusStr == "1_STOPPED_MANUAL": self.mStatusStr = "5_STARTED_MANUAL"; lLogBool=True
if self.mStatusStr == "0_STOPPED": self.mStatusStr = "4_STARTED"; lLogBool=True if self.mStatusStr == "0_STOPPED": self.mStatusStr = "4_STARTED"; lLogBool=True
@ -420,6 +421,10 @@ class Process():
if lLogBool == True: self.StatusChangeLog() if lLogBool == True: self.StatusChangeLog()
self.mAgentMuteBool = False self.mAgentMuteBool = False
return self.mStatusStr return self.mStatusStr
except Exception as e:
self.mAgentMuteBool=False
raise e
def StatusCheckStart(self): def StatusCheckStart(self):
""" """
Check process status and run it if auto stopped self.mStatusStr is "0_STOPPED" Check process status and run it if auto stopped self.mStatusStr is "0_STOPPED"

@ -604,6 +604,15 @@ def BackwardCompatibityWrapperNoAuth(inRequest:Request, inResponse:Response, inB
if lHTTPRequest.OpenRPAResponseDict["Headers"]["Content-type"] != None: if lHTTPRequest.OpenRPAResponseDict["Headers"]["Content-type"] != None:
return StreamingResponse(io.BytesIO(lResult), media_type=lHTTPRequest.OpenRPAResponseDict["Headers"]["Content-type"]) return StreamingResponse(io.BytesIO(lResult), media_type=lHTTPRequest.OpenRPAResponseDict["Headers"]["Content-type"])
# Get thread list
@app.get(path="/threads",response_class=PlainTextResponse)
def Threads():
lThreadStr = ""
for thread in threading.enumerate():
lThreadStr+=f"ПОТОК: {thread.name}\n"
#print(thread.name)
return lThreadStr
def InitFastAPI(): def InitFastAPI():
global gSettingsDict global gSettingsDict
global app global app

@ -110,7 +110,7 @@ def AgentActivityItemReturnExists(inGUIDStr, inGSettings = None):
return inGUIDStr in inGSettings["AgentActivityReturnDict"] return inGUIDStr in inGSettings["AgentActivityReturnDict"]
def AgentActivityItemReturnGet(inGUIDStr, inCheckIntervalSecFloat = 0.5, inGSettings=None): def AgentActivityItemReturnGet(inGUIDStr, inCheckIntervalSecFloat = 0.5, inGSettings=None, inTimeoutSecFloat=None):
"""L+,W+: Ожидает появления результата по активности (ActivityItem). Возвращает результат выполнения активности. """L+,W+: Ожидает появления результата по активности (ActivityItem). Возвращает результат выполнения активности.
!ВНИМАНИЕ! Замораживает поток, пока не будет получен результат. !ВНИМАНИЕ! Замораживает поток, пока не будет получен результат.
@ -122,15 +122,21 @@ def AgentActivityItemReturnGet(inGUIDStr, inCheckIntervalSecFloat = 0.5, inGSett
:return: Результат выполнения активности. !ВНИМАНИЕ! Возвращаются только то результаты, которые могут быть интерпретированы в JSON формате. :return: Результат выполнения активности. !ВНИМАНИЕ! Возвращаются только то результаты, которые могут быть интерпретированы в JSON формате.
""" """
inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings
lTimeStampSecFloat = time.time()
#Check if Orchestrator has been initialized - else raise exception #Check if Orchestrator has been initialized - else raise exception
if Core.IsOrchestratorInitialized(inGSettings=inGSettings) == True: if Core.IsOrchestratorInitialized(inGSettings=inGSettings) == True:
# Wait while result will not come here # Wait while result will not come here
while not AgentActivityItemReturnExists(inGSettings=inGSettings, inGUIDStr=inGUIDStr): lLoopBool = True
while lLoopBool:
if not AgentActivityItemReturnExists(inGSettings=inGSettings, inGUIDStr=inGUIDStr):
time.sleep(inCheckIntervalSecFloat) time.sleep(inCheckIntervalSecFloat)
else: lLoopBool=False
if (inTimeoutSecFloat is not None) and (time.time() - lTimeStampSecFloat) >= inTimeoutSecFloat:
raise Exception(f"Orchestrator.AgentActivityItemReturnGet !ВНИМАНИЕ! ПРЕВЫШЕНО ВРЕМЯ ОЖИДАНИЯ ОТВЕТА")
# Return the result # Return the result
return inGSettings["AgentActivityReturnDict"][inGUIDStr]["Return"] return inGSettings["AgentActivityReturnDict"][inGUIDStr]["Return"]
else: else:
raise Exception(f"__Orchestrator__.AgentActivityItemReturnGet !ATTENTION! Use this function only after Orchestrator initialization! Before orchestrator init exception will be raised.") raise Exception(f"Orchestrator.AgentActivityItemReturnGet !ВНИМАНИЕ! ФУНКЦИЯ МОЖЕТ БЫТЬ ЗАПУЩЕНА ТОЛЬКО ПОСЛЕ ИНИЦИАЛИЗАЦИИ!")
def AgentOSCMD(inHostNameStr, inUserStr, inCMDStr, inRunAsyncBool=True, inSendOutputToOrchestratorLogsBool=True, inCMDEncodingStr="cp1251", inGSettings=None, inCaptureBool=True): def AgentOSCMD(inHostNameStr, inUserStr, inCMDStr, inRunAsyncBool=True, inSendOutputToOrchestratorLogsBool=True, inCMDEncodingStr="cp1251", inGSettings=None, inCaptureBool=True):
"""L+,W+: Отправка команды командной строки на сессию, где работает pyOpenRPA.Agent. Результат выполнения команды можно выводить в лог оркестратора. """L+,W+: Отправка команды командной строки на сессию, где работает pyOpenRPA.Agent. Результат выполнения команды можно выводить в лог оркестратора.
@ -535,6 +541,7 @@ def OSCMD(inCMDStr, inRunAsyncBool=True, inLogger = None):
# New call # New call
if inRunAsyncBool: if inRunAsyncBool:
lThread = threading.Thread(target=_CMDRunAndListenLogs, kwargs={"inCMDStr":inCMDStr, "inLogger":inLogger}) lThread = threading.Thread(target=_CMDRunAndListenLogs, kwargs={"inCMDStr":inCMDStr, "inLogger":inLogger})
lThread.setName("OSCMD_ACTIVITY")
lThread.start() lThread.start()
lResultStr="Список ActivityList был запущен в асинхронном режиме - захватить содержимое невозможно" lResultStr="Список ActivityList был запущен в асинхронном режиме - захватить содержимое невозможно"
else: else:
@ -594,6 +601,7 @@ def OrchestratorThreadStart(inDef, *inArgList, **inArgDict):
:return: threading.Thread экземпляр :return: threading.Thread экземпляр
""" """
lDefThread = threading.Thread(target=inDef,args=inArgList,kwargs=inArgDict) lDefThread = threading.Thread(target=inDef,args=inArgList,kwargs=inArgDict)
lDefThread.setName(f"ORCHESTRATOR_THREAD_{str(inDef).upper()}")
lDefThread.start() lDefThread.start()
return lDefThread return lDefThread
@ -706,6 +714,7 @@ def OrchestratorPySearchInit(inGlobPatternStr, inDefStr = None, inDefArgNameGSet
lThreadInit = threading.Thread(target=__execute__,kwargs={ lThreadInit = threading.Thread(target=__execute__,kwargs={
"inResultDict":lResultDict, "inPyPathItemStr": lPyPathItemStr, "inResultDict":lResultDict, "inPyPathItemStr": lPyPathItemStr,
"inDefStr": inDefStr, "inDefArgNameGSettingsStr": inDefArgNameGSettingsStr}, daemon=True) "inDefStr": inDefStr, "inDefArgNameGSettingsStr": inDefArgNameGSettingsStr}, daemon=True)
lThreadInit.setName("PY_SEARCH_MODULE_INIT")
lThreadInit.start() lThreadInit.start()
else: else:
# SYNC EXECUTION # SYNC EXECUTION
@ -1964,6 +1973,7 @@ def ProcessDefIntervalCall(inDef, inIntervalSecFloat, inIntervalAsyncBool=False,
lThread2 = threading.Thread(target=inDef, lThread2 = threading.Thread(target=inDef,
args=inDefArgList, args=inDefArgList,
kwargs=inDefArgDict) kwargs=inDefArgDict)
lThread2.setName("INTERVAL_CALL_DEF")
lThread2.start() lThread2.start()
except Exception as e: except Exception as e:
if inLogger: inLogger.exception( if inLogger: inLogger.exception(
@ -1978,6 +1988,7 @@ def ProcessDefIntervalCall(inDef, inIntervalSecFloat, inIntervalAsyncBool=False,
"inIntervalAsyncBool": inIntervalAsyncBool, "inDefArgList": inDefArgList, "inIntervalAsyncBool": inIntervalAsyncBool, "inDefArgList": inDefArgList,
"inDefArgDict": inDefArgDict, "inLogger": inLogger, "inDefArgDict": inDefArgDict, "inLogger": inLogger,
"inDefArgGSettingsNameStr":inDefArgGSettingsNameStr , "inDefArgLoggerNameStr":inDefArgLoggerNameStr}) "inDefArgGSettingsNameStr":inDefArgGSettingsNameStr , "inDefArgLoggerNameStr":inDefArgLoggerNameStr})
lThread.setName("INTERVAL_CALL_EXECUTOR")
lThread.start() lThread.start()
else: else:
__Execute__(inGSettings=inGSettings, inDef=inDef, inIntervalSecFloat=inIntervalSecFloat, inIntervalAsyncBool=inIntervalAsyncBool, __Execute__(inGSettings=inGSettings, inDef=inDef, inIntervalSecFloat=inIntervalSecFloat, inIntervalAsyncBool=inIntervalAsyncBool,
@ -2734,7 +2745,7 @@ def Orchestrator(inGSettings=None, inDumpRestoreBool = True, inRunAsAdministrato
# Run SettingUpdate function in submodule # Run SettingUpdate function in submodule
getattr(lTechModuleFromSpec, lSubmoduleFunctionName)(gSettingsDict) getattr(lTechModuleFromSpec, lSubmoduleFunctionName)(gSettingsDict)
except Exception as e: except Exception as e:
if lL: lL.exception(f"Error when init .py file in orchestrator '{lModuleFilePathItem}'. Exception is below:") if lL: lL.exception(f"Ошибка при инициализации .py файлов в оркестраторе '{lModuleFilePathItem}'")
# Turn on backward compatibility # Turn on backward compatibility
BackwardCompatibility.Update(inGSettings= gSettingsDict) BackwardCompatibility.Update(inGSettings= gSettingsDict)
@ -2757,6 +2768,7 @@ def Orchestrator(inGSettings=None, inDumpRestoreBool = True, inRunAsAdministrato
# Init the RobotScreenActive in another thread # Init the RobotScreenActive in another thread
lRobotScreenActiveThread = threading.Thread(target= Monitor.CheckScreen) lRobotScreenActiveThread = threading.Thread(target= Monitor.CheckScreen)
lRobotScreenActiveThread.daemon = True # Run the thread in daemon mode. lRobotScreenActiveThread.daemon = True # Run the thread in daemon mode.
lRobotScreenActiveThread.setName("SCREEN_ACTIVE")
lRobotScreenActiveThread.start() # Start the thread execution. lRobotScreenActiveThread.start() # Start the thread execution.
if lL: lL.info("Модуль активного рабочего стола инициализирован") #Logging if lL: lL.info("Модуль активного рабочего стола инициализирован") #Logging
@ -2764,12 +2776,14 @@ def Orchestrator(inGSettings=None, inDumpRestoreBool = True, inRunAsAdministrato
lRobotRDPThreadControlDict = {"ThreadExecuteBool":True} # inThreadControlDict = {"ThreadExecuteBool":True} lRobotRDPThreadControlDict = {"ThreadExecuteBool":True} # inThreadControlDict = {"ThreadExecuteBool":True}
lRobotRDPActiveThread = threading.Thread(target= RobotRDPActive.RobotRDPActive, kwargs={"inGSettings":gSettingsDict, "inThreadControlDict":lRobotRDPThreadControlDict}) lRobotRDPActiveThread = threading.Thread(target= RobotRDPActive.RobotRDPActive, kwargs={"inGSettings":gSettingsDict, "inThreadControlDict":lRobotRDPThreadControlDict})
lRobotRDPActiveThread.daemon = True # Run the thread in daemon mode. lRobotRDPActiveThread.daemon = True # Run the thread in daemon mode.
lRobotRDPActiveThread.setName("RDP_CONNECT")
lRobotRDPActiveThread.start() # Start the thread execution. lRobotRDPActiveThread.start() # Start the thread execution.
if lL: lL.info("Модуль подключения по РДП инициализированн") #Logging if lL: lL.info("Модуль подключения по РДП инициализированн") #Logging
# Init autocleaner in another thread # Init autocleaner in another thread
lAutocleanerThread = threading.Thread(target= GSettingsAutocleaner, kwargs={"inGSettings":gSettingsDict}) lAutocleanerThread = threading.Thread(target= GSettingsAutocleaner, kwargs={"inGSettings":gSettingsDict})
lAutocleanerThread.daemon = True # Run the thread in daemon mode. lAutocleanerThread.daemon = True # Run the thread in daemon mode.
lAutocleanerThread.setName("AUTOCLEANER")
lAutocleanerThread.start() # Start the thread execution. lAutocleanerThread.start() # Start the thread execution.
if lL: lL.info("Модуль автоочистки инициализирован") #Logging if lL: lL.info("Модуль автоочистки инициализирован") #Logging
@ -2784,24 +2798,28 @@ def Orchestrator(inGSettings=None, inDumpRestoreBool = True, inRunAsAdministrato
# Processor thread # Processor thread
lProcessorThread = threading.Thread(target= Processor.ProcessorRunSync, kwargs={"inGSettings":gSettingsDict, "inRobotRDPThreadControlDict":lRobotRDPThreadControlDict}) lProcessorThread = threading.Thread(target= Processor.ProcessorRunSync, kwargs={"inGSettings":gSettingsDict, "inRobotRDPThreadControlDict":lRobotRDPThreadControlDict})
lProcessorThread.daemon = True # Run the thread in daemon mode. lProcessorThread.daemon = True # Run the thread in daemon mode.
lProcessorThread.setName("PROCESSOR")
lProcessorThread.start() # Start the thread execution. lProcessorThread.start() # Start the thread execution.
if lL: lL.info("Модуль процессора инициализирован") #Logging if lL: lL.info("Модуль процессора инициализирован") #Logging
# Processor monitor thread # Processor monitor thread
lProcessorMonitorThread = threading.Thread(target= Processor.ProcessorMonitorRunSync, kwargs={"inGSettings":gSettingsDict}) lProcessorMonitorThread = threading.Thread(target= Processor.ProcessorMonitorRunSync, kwargs={"inGSettings":gSettingsDict})
lProcessorMonitorThread.daemon = True # Run the thread in daemon mode. lProcessorMonitorThread.daemon = True # Run the thread in daemon mode.
lProcessorMonitorThread.setName("PROCESSOR_MONITOR")
lProcessorMonitorThread.start() # Start the thread execution. lProcessorMonitorThread.start() # Start the thread execution.
if lL: lL.info("Модуль контроля процессора инициализирован") #Logging if lL: lL.info("Модуль контроля процессора инициализирован") #Logging
# Scheduler loop # Scheduler loop
lSchedulerThread = threading.Thread(target= __deprecated_orchestrator_loop__) lSchedulerThread = threading.Thread(target= __deprecated_orchestrator_loop__)
lSchedulerThread.daemon = True # Run the thread in daemon mode. lSchedulerThread.daemon = True # Run the thread in daemon mode.
lSchedulerThread.setName("SCHEDULER_OLD")
lSchedulerThread.start() # Start the thread execution. lSchedulerThread.start() # Start the thread execution.
if lL: lL.info("Модуль расписания (старая версия) инициализирован") #Logging if lL: lL.info("Модуль расписания (старая версия) инициализирован") #Logging
# Schedule (new) loop # Schedule (new) loop
lScheduleThread = threading.Thread(target= __schedule_loop__) lScheduleThread = threading.Thread(target= __schedule_loop__)
lScheduleThread.daemon = True # Run the thread in daemon mode. lScheduleThread.daemon = True # Run the thread in daemon mode.
lScheduleThread.setName("SCHEDULER_NEW")
lScheduleThread.start() # Start the thread execution. lScheduleThread.start() # Start the thread execution.
if lL: lL.info("Модуль расписания (новая версия) инициализирован") #Logging if lL: lL.info("Модуль расписания (новая версия) инициализирован") #Logging
@ -2810,10 +2828,10 @@ def Orchestrator(inGSettings=None, inDumpRestoreBool = True, inRunAsAdministrato
lProcess = inGSettings["ManagersProcessDict"][lProcessKeyTuple] lProcess = inGSettings["ManagersProcessDict"][lProcessKeyTuple]
lProcess.StatusCheckIntervalRestore() lProcess.StatusCheckIntervalRestore()
lThread = threading.Thread(target= lProcess.StatusRestore) lThread = threading.Thread(target= lProcess.StatusRestore)
lThread.setName("MANAGER_PROCESS_RESTORE")
lThread.start() lThread.start()
# Init debug thread (run if "init_dubug" file exists) # Init debug thread (run if "init_dubug" file exists)
Debugger.LiveDebugCheckThread(inGSettings=GSettingsGet()) Debugger.LiveDebugCheckThread(inGSettings=GSettingsGet())
@ -2890,6 +2908,7 @@ def __deprecated_orchestrator_loop__():
lThread = threading.Thread(target=Processor.ActivityListExecute, lThread = threading.Thread(target=Processor.ActivityListExecute,
kwargs={"inGSettings": inGSettings, kwargs={"inGSettings": inGSettings,
"inActivityList": lItem["ActivityList"]}) "inActivityList": lItem["ActivityList"]})
lThread.setName("SCHEDULER_OLD_ACTIVITY")
lThread.start() lThread.start()
lIterationLastDateTime = datetime.datetime.now() # Set the new datetime for the new processor activity lIterationLastDateTime = datetime.datetime.now() # Set the new datetime for the new processor activity
except Exception as e: except Exception as e:

@ -20,4 +20,5 @@ def LiveDebugCheckThread(**inKWARGS):
global gKWARGS global gKWARGS
gKWARGS = inKWARGS gKWARGS = inKWARGS
lThread = threading.Thread(target=LiveDebugCheckLoop) lThread = threading.Thread(target=LiveDebugCheckLoop)
lThread.setName("DEBUG_LIVE")
lThread.start() lThread.start()
Loading…
Cancel
Save