def ___proxy_finish_request(MsgHdlr, MsgBody, FutRet): ''' Finish a Msg request to a servicing Worker ''' Attempt = 1 MsgIdSet = False # Want to set this once State = ProxyState.CONN # Enter the state machine while Attempt <= Max_Msg_Request_Attempts: if State == ProxyState.CONN: MsgHdlr, MsgId = connect_to_server( MsgBody.ServerAddr, Attempt) # MsgId invalid after Attempt = 1 if MsgHdlr != None: if MsgIdSet == False: MsgBody.MsgId = ResultsCacheKey(my_Ip(), my_Port(), MsgId) MsgIdSet = True # Request init is complete State = ProxyState.SEND_REQU continue else: Attempt += 1 continue elif State == ProxyState.SEND_REQU: if send_request_to_server(MsgHdlr, MsgBody) == False: MsgHdlr.close() Attempt += 1 State = ProxyState.CONN continue else: State = ProxyState.RECV_RET elif State == ProxyState.RECV_RET: RetBody = recv_response_from_server(MsgHdlr, MsgBody) if RetBody == None: MsgHdlr.close() Attempt += 1 State = ProxyState.CONN continue # success else: MsgHdlr.close() FutRet.__set_result_and_unlock__(RetBody) return FutRet # all attempts failed raise AsyncLocalMaxRetries( \ f'{MsgBody.ClientAddr} finish__request to {MsgBody.ServerAddr}: {Max_Msg_Request_Attempts} attempts failed!')
def my_ExtName(self): ''' Returns a new ExtName for the Corps instance ''' # todo: after we implement to_ExtName(), maybe rewrite using Conc's verion and converting SelfClassName = self.__class__.__name__ CallingModuleName = self.__class__.__module__ CallingModule = import_module(CallingModuleName) CorpsClassProxy = proxy(self.__class__, SelfClassName + 'Name', CallingModule) NewProxy = CorpsClassProxy(ConcAddr_to_ExtAddr(self.ConcAddr, my_Ip(), my_Port())) NewName = Name(NewProxy, SelfClassName, CallingModuleName) return NewName
def __other_process_create_Corps__(CallingModuleName, CorpsClassName, WorkerQueue, *args, **kwargs): ''' Create a Corps in a new process (assumes we are running in that process) ''' # Find the CorpsClass object # todo: exceptions upon either step failing TheCallingModule = import_module(CallingModuleName) CorpsClassInModule = getattr(TheCallingModule, CorpsClassName) # Create the Corps NewCorps = CorpsClassInModule(*args, **kwargs) # Return data to calling process WorkerQueue.put([my_Ip(), my_Port()]) return True
def create_Corps(self, ModuleName, CorpsClassName, CorpsTag, Ext, Managed, LocType, LocVal, *args, **kwargs): if Managed == True: kwargs['ConfigDicts'].append({'MgrCorpsIpPort': (my_Ip(), my_Port())}) WorkerQueue = Queue() NewCorpsProcess = Process(target=Workers.__other_process_create_Corps__, \ args=(ModuleName, CorpsClassName, WorkerQueue, *args), kwargs=kwargs) NewCorpsProcess.start() NewCorpsData = WorkerQueue.get() NewCorps_Ip = NewCorpsData[0] NewCorps_Port = NewCorpsData[1] NewCorpsEnvRecord = CorpsEnvRecord(CorpsTag, DefaultEnvRecord.MsgHdlrFactory, DefaultEnvRecord.NetwFactory, \ NewCorps_Ip, NewCorps_Port) NewCorps_EnvId = CORPSMGR_ENVID if Managed == True: if Ext == True: NewCorps_EnvId = _ExtCorpsEnvTable.register(None, NewCorpsEnvRecord) else: NewCorps_EnvId = _ContCorpsEnvTable.register(None, NewCorpsEnvRecord) NewXferCorpsEnvRecord = XferCorpsEnvRecord(CorpsTag, NewCorps_EnvId, NewCorps_Ip, NewCorps_Port) # Add new Corps to all Envs except ours if Managed == True: NumEnvs = _EnvTable.num_Envs() # assumes EnvIds are sequential (not true for ContCorps and ExtCorps) EnvNames = EnvNameGen(MIN_ENVID_plus_1, NumEnvs-1) FutRets = [] for RemoteEnv in EnvNames: FutRets.append(RemoteEnv.add2_CorpsEnvTable(NewCorps_EnvId, Ext, NewXferCorpsEnvRecord)) for FutRet in FutRets: Ret = FutRet.Ret # will blow up if we have an exception return NewXferCorpsEnvRecord
def ___proxy_make_request(self, ServerAddr, MethodName, *Args, **KwArgs): ''' Initiate a Msg request to a servicing Worker ''' from ConfigGlobals import Max_Msg_Request_Attempts TheConcAddr = TheThread.TheConcAddr # the client Conc whose Thread is running and who called the proxy # from EnvGlobals import NullConcAddr # if TheConcAddr == NullConcAddr: # print(f'proxy: Null ConcAddr on request to {ServerAddr} for {MethodName}()') # Initialize a request MsgBody = CorpsRequest() MsgBody.MsgType = CorpsMsgType.ConcRequ NoReply = 'NoReply' NoReplyFlag = False if NoReply in KwArgs: if KwArgs[NoReply] == True: MsgBody.MsgFlags |= NoReplyBitMask NoReplyFlag = True del KwArgs[NoReply] MsgBody.MsgId = ResultsCacheKey(my_Ip(), my_Port(), _MsgIdMgr.new()) MsgBody.ClientAddr = TheConcAddr MsgBody.ServerAddr = ServerAddr MsgBody.MethodName = MethodName MsgBody.Args = Args MsgBody.KwArgs = KwArgs Attempt = 1 State = ProxyState.CONN # Enter the state machine while Attempt <= Max_Msg_Request_Attempts: # $ need to handle connect errors if State == ProxyState.CONN: MsgHdlr = connect_to_server(ServerAddr) if MsgHdlr != None: State = ProxyState.SEND_REQU continue else: Attempt += 1 continue elif State == ProxyState.SEND_REQU: if send_request_to_server(MsgHdlr, MsgBody) == False: MsgHdlr.close() Attempt += 1 State = ProxyState.CONN continue # success...if client does not want a reply from the service return a None # otw schedule ___proxy_finish_request for another thread and return Future to client # State is now implicitly ProxyState.RECV_RET for ___proxy_finish_request else: FutRet = Future() if NoReplyFlag == True: RetBody = CorpsReturn() RetBody.Ret = None RetBody.MsgType = CorpsMsgType.ConcRet RetBody.ClientAddr = MsgBody.ClientAddr RetBody.ServerAddr = MsgBody.ServerAddr FutRet.__set_result_and_unlock__(RetBody) MsgHdlr.close() else: cmd = lambda: ___proxy_finish_request(MsgHdlr, MsgBody, FutRet, Attempt) _ThreadPool.put_cmd(cmd) # cmd = lambda: ___proxy_finish_request(MsgHdlr, MsgBody, FutRet, Attempt) # _ThreadPool.put_cmd(cmd) return FutRet # all attempts failed raise AsyncLocalMaxRetries( \ f'{MsgBody.ClientAddr} make_request to {MsgBody.ServerAddr}: {Max_Msg_Request_Attempts} attempts failed!')