diff --git a/Sources/pyOpenRPA/Orchestrator/Managers/Process.py b/Sources/pyOpenRPA/Orchestrator/Managers/Process.py index 31b98a9f..c224a1b1 100644 --- a/Sources/pyOpenRPA/Orchestrator/Managers/Process.py +++ b/Sources/pyOpenRPA/Orchestrator/Managers/Process.py @@ -36,6 +36,11 @@ class Process(): mStopSafeTimeoutSecFloat = None mStatusStr = None # 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL + # MST - Manual Stop Trigger + mMSTdTSecFloat: float = None + mMSTdNInt = None + mMSTStartTimeList = [] + def __init__(self, inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr = None, inStopSafeTimeoutSecFloat=120): self.mAgentHostNameStr = inAgentHostNameStr self.mAgentUserNameStr = inAgentUserNameStr @@ -47,6 +52,40 @@ class Process(): lActivityDict = __Orchestrator__.ProcessorActivityItemCreate(inDef=self.StatusCheck,inArgList=[]) __Orchestrator__.ProcessorActivityItemAppend(inActivityItemDict=lActivityDict) + def ManualStopTriggerSet(self, inMSTdTSecFloat: float, inMSTdNInt: int) -> None: + """ + Set ManualStopTrigger (MST) to switch to STOPPED MANUAL if specified count of start fails will be catched in specified time period + + :param inMSTdTSecFloat: Time perios in seconds + :param inMSTdNInt: Counts of the start tries + :return: None + """ + + # MST - Manual Stop Trigger + self.mMSTdTSecFloat = inMSTdTSecFloat + self.mMSTdNInt = inMSTdNInt + + + def ManualStopTriggerNewStart(self): + """ + Log new start event. Check if it is applicable. Change status if ManualStop trigger criteria is applied + + :return: # 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL + """ + if self.mMSTdTSecFloat is not None and self.mMSTdNInt is not None: + lTimeNowSecFloat = time.time() + self.mMSTStartTimeList.append(lTimeNowSecFloat) # Append current time to MST list + # Remove old items from list + lMSTStartTimeList = [] + for lTimeItemSecFloat in self.mMSTStartTimeList: + ldTSecFloat = lTimeNowSecFloat - lTimeItemSecFloat + # Move to the new list if dT less + if ldTSecFloat < self.mMSTdTSecFloat: lMSTStartTimeList.append(lTimeItemSecFloat) + self.mMSTStartTimeList = lMSTStartTimeList # Set new list + # Check count in list + if len(lMSTStartTimeList) > self.mMSTdNInt: self.mStatusStr = "1_STOPPED_MANUAL" + return self.mStatusStr + def Manual2Auto(self) -> str: """ Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self): @@ -63,11 +102,18 @@ class Process(): def Start(self, inIsManualBool = True) -> str: """ - Manual/Auto start. Manual start will block scheduling execution. To return schedule execution use def Manual2Auto + Manual/Auto start. Manual start will block scheduling execution. To return schedule execution use def Manual2Auto. + Will not start if STOP SAFE is now and don't start auto is stopped manual now :param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL """ + if (self.mStatusStr == "1_STOPPED_MANUAL" or "STOP_SAFE" in self.mStatusStr) and inIsManualBool == False: + lStr = f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Process will not start because of stopped manual or stop safe is now." + __Orchestrator__.OrchestratorLoggerGet().warning(lStr) + return self.mStatusStr + if inIsManualBool == False: self.ManualStopTriggerNewStart() # Set the time + # Send activity item to agent - wait result if self.mStartPathStr is not None: lCMDStr = f"start {os.path.abspath(self.mStartPathStr)}" elif self.mStartCMDStr is not None: lCMDStr = f"start {self.mStartCMDStr}"