# 1.2.0 - general processor - contains old orchestrator processor + RDPActive processor import time, copy, threading, uuid # Run processor synchronious # inThreadControlDict = {"ThreadExecuteBool":True} def ProcessorRunSync(inGSettings, inRobotRDPThreadControlDict): """ "ProcessorDict": { # Has been changed. New general processor (one threaded) v.1.2.0 "ActivityList": [ # List of the activities # { # "Def":"DefAliasTest", # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) # "ArgList":[1,2,3], # Args list # "ArgDict":{"ttt":1,"222":2,"dsd":3}, # Args dictionary # "ArgGSettings": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) # "ArgLogger": None ,# Name of GSettings attribute: str (ArgDict) or index (for ArgList) # "GUIDStr": "" # }, ], "AliasDefDict": {}, # Storage for def with Str alias. To use it see pyOpenRPA.Orchestrator.ControlPanel "CheckIntervalSecFloat": 1.0 # Interval for check gSettings in ProcessorDict > ActivityList "ExecuteBool": True # Flag to execute thread processor """ lL = inGSettings["Logger"] # Logger alias inGSettings["ProcessorDict"]["ThreadIdInt"] = threading.get_ident() # fill Processor thread id try: while inGSettings["ProcessorDict"]["ExecuteBool"]: lActivityList = inGSettings["ProcessorDict"]["ActivityList"] # Alias if len(lActivityList)>0: if lL: lL.debug(f'Processor ActivityList len: {len(lActivityList)}') lActivityItem = inGSettings["ProcessorDict"]["ActivityList"].pop(0) # Extract the first item from processor queue if lActivityItem.get("ThreadBool", False) is False: inRobotRDPThreadControlDict["ThreadExecuteBool"]=False # Stop the RobotRDPActive monitoring inGSettings["ProcessorDict"]["ActivityItemNowDict"]=lActivityItem ActivityListExecute(inGSettings = inGSettings, inActivityList = [lActivityItem]) # execute the activity item inGSettings["ProcessorDict"]["ActivityItemNowDict"]=None inRobotRDPThreadControlDict["ThreadExecuteBool"] = True # Continue the RobotRDPActive monitoring else: ProcessorRunAsync(inGSettings = inGSettings, inActivityList=[lActivityItem]) else: time.sleep(inGSettings["ProcessorDict"]["CheckIntervalSecFloat"]) # Sleep when list is empty except Exception as e: if lL: lL.exception(f"Processor.ProcessorRunSync. Something goes very wrong in processor queue. See traceback") # Run processor Async def ProcessorRunAsync(inGSettings, inActivityList): """ "inActivityList": [ # List of the activities # { # "Def":"DefAliasTest", # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) # "ArgList":[1,2,3], # Args list # "ArgDict":{"ttt":1,"222":2,"dsd":3}, # Args dictionary # "ArgGSettings": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) # "ArgLogger": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) # "GUIDStr": "sadasd-asdas-d-asdasd", # ActivityItem GUID which identify the Activity # "ThreadBool": True # }, """ def __process__(inGSettings, inActivityList): for lActivityItem in inActivityList: lL = inGSettings["Logger"] # Logger alias if lL: lL.debug(f'ActivityItem in new thread') lResultList = ActivityListExecute(inGSettings = inGSettings, inActivityList = [lActivityItem]) # execute the activity item # Start in new thread lThread = threading.Thread(target=__process__,kwargs={"inGSettings": inGSettings, "inActivityList": inActivityList}) lThread.start() # Execute ActivityItem list # return the def result def ActivityListExecute(inGSettings, inActivityList): lL = inGSettings["Logger"] # Logger alias lResultList = [] # init the result list try: for lActivityItem in inActivityList: # Iterate throught the activity list if lL: lL.info(f'Процессор:: Исполнение функции def:{str(lActivityItem["Def"])}. В целях информационной безопасности параметры недоступны для просмотра') lDef = None # Def variable if callable(lActivityItem["Def"]): # CHeck if def is callable lDef = lActivityItem["Def"] # Get the def else: # Is not callable - check alias lDef = inGSettings["ProcessorDict"]["AliasDefDict"].get(lActivityItem["Def"], None) # get def if def key in Alias def storage #gSettings lGSettingsDictKey = lActivityItem.pop("ArgGSettings",None) # # Prepare arg dict - gSettings if type(lGSettingsDictKey) is str and lGSettingsDictKey != "": # check if gSetting key is in ArgDict 13.02.2021 - Fix when ArgGSettings is "" lActivityItem["ArgDict"][lGSettingsDictKey] = inGSettings # Set the gSettings in dict # # Prepare arg list elif type(lGSettingsDictKey) is int: # check if gSetting key is in ArgDict lActivityItem["ArgList"].insert(lGSettingsDictKey,inGSettings)# Set the gSettings in list by the index #Logger lLoggerDictKey = lActivityItem.pop("ArgLogger",None) # # Prepare arg dict - Logger if type(lLoggerDictKey) is str and lLoggerDictKey != "": # check if gSetting key is in ArgDict 13.02.2021 - Fix when ArgLogger is "" lActivityItem["ArgDict"][lLoggerDictKey] = lL # Set the lLogger in dict # # Prepare arg list elif type(lLoggerDictKey) is int: # check if gSetting key is in ArgDict lActivityItem["ArgList"].insert(lLoggerDictKey,lL)# Set the lLogger in list by the index try: # try to run function from Processor.py lActivityItemResult = lDef(*lActivityItem["ArgList"], **lActivityItem["ArgDict"]) lResultList.append(lActivityItemResult) # return the result except Exception as e: if lL: lL.exception(f"pyOpenRPA Processor.ActivityListExecute: Exception in def execution - activity will be ignored.") # Logging lResultList.append(e) # return the generated exception except Exception as e: if lL: lL.exception(f"pyOpenRPA Processor.ActivityListExecute: Exception when initialisation - All activity list will be ignored.") # Logging return lResultList # return the result list def __ActivityListVerify__(inActivityList): """ Verify ActivityList variable - raise exception if input list is not list of dict with structure: # "Def":"DefAliasTest", # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) # "ArgList":[1,2,3], # Args list # "ArgDict":{"ttt":1,"222":2,"dsd":3}, # Args dictionary # "ArgGSettings": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) # "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) :param inActivityList: :return: """ # CASE LIST if type(inActivityList) is list: for lItem in inActivityList: # CASE LIST item is LIST if type(lItem) is list: raise Exception(f"pyOpenRPA Processor.__ActivityListVerify__: inActivityList has wrong structure! Details: Your ActivityList item is list too. List of the list :(") # CASE Item is not dict if type(lItem) is not dict: raise Exception(f"pyOpenRPA Processor.__ActivityListVerify__: inActivityList has wrong structure! Details: Your ActivityList item is is not dict") # CASE HAS NO "Def" if "Def" not in lItem: raise Exception(f"pyOpenRPA Processor.__ActivityListVerify__: inActivityList has wrong structure! Details: Activity item has no attribute 'Def'") #CASE NOT LIST else: raise Exception(f"pyOpenRPA Processor.__ActivityListVerify__: inActivityList has wrong structure! Details: Your ActivityList is not a list.") def ProcessorMonitorRunSync(inGSettings): """ Periodically check processor queue if task is updating. If one task is more than ... sec - send warning in log """ lL = inGSettings["Logger"] # Logger alias lActiveGUIDStr = None lActiveTimeStart = time.time() try: while True: if inGSettings["ProcessorDict"]["ActivityItemNowDict"] is not None: lItemDict = inGSettings["ProcessorDict"]["ActivityItemNowDict"] if "GUIDStr" not in lItemDict: lGUIDStr = str(uuid.uuid4()) # generate new GUID lItemDict["GUIDStr"] = lGUIDStr # Check if GUID is identical if lItemDict["GUIDStr"]==lActiveGUIDStr: # Check time lActiveTimeDeltaSec = time.time() - lActiveTimeStart # If delta more than Warning limit sec float lWaitTimeSecFloat = inGSettings["ProcessorDict"]["WarningExecutionMoreThanSecFloat"] if lActiveTimeDeltaSec > lWaitTimeSecFloat: if lL: lL.warning(f"Processor.ProcessorMonitorRunSync: Processor wait more than {lWaitTimeSecFloat} sec. Activity def: {lItemDict['Def']}; GUID: {lItemDict['GUIDStr']}") else: lActiveGUIDStr = lItemDict["GUIDStr"] lActiveTimeStart = time.time() time.sleep(inGSettings["ProcessorDict"]["WarningExecutionMoreThanSecFloat"]) # Sleep when list is empty except Exception as e: if lL: lL.exception( f"Processor.ProcessorMonitorRunSync. Something goes very wrong in processor queue. See traceback")