def _makeDispatcher(self, connection): self.debugMsg("_makeDispatcher()") self.dispatcher = ActorDispatcher( connection=connection, name=self._dictName, # name of keyword dictionary ) # initialize a command queue self.cmdQueue = DispatcherCmdQueue(self.dispatcher)
def _makeDispatcher(self, connection): self.debugMsg("_makeDispatcher()") self.dispatcher = ActorDispatcher( connection = connection, name = self._dictName, # name of keyword dictionary ) # initialize a command queue self.cmdQueue = DispatcherCmdQueue(self.dispatcher)
class DispatcherWrapper(BaseWrapper): """!A wrapper for an opscore.ActorDispatcher talking to an wrapped actor This wrapper is responsible for starting and stopping everything: - It builds an actor dispatcher when the actor wrapper is ready - It stops the actor wrapper and actor dispatcher on close() Public attributes include: - actorWrapper: the actor wrapper (twistedActor.ActorWrapper) - dispatcher: the actor dispatcher (twistedActor.ActorDispatcher); None until ready - readyDeferred: called when the dispatcher is ready (for tracking closure use the Deferred returned by the close method, or stateCallback). """ def __init__(self, actorWrapper, dictName, name = "", readCallback = None, stateCallback = None, debug = False, ): """!Construct a DispatcherWrapper that manages everything @param[in] actorWrapper actor wrapper (twistedActor.ActorWrapper); must be starting up or ready @param[in] dictName name of actor keyword dictionary @param[in] name a name to use for messages @param[in] readCallback function to call when the actor dispatcher has data to read @param[in] stateCallback function to call when connection state of of any socket changes; receives one argument: this actor wrapper @param[in] debug print debug messages to stdout? """ BaseWrapper.__init__(self, name = name, stateCallback = stateCallback, callNow = False, debug = debug, ) self.actorWrapper = actorWrapper self._dictName = dictName self._readCallback = readCallback self.dispatcher = None # the ActorDispatcher, once it's built self.actorWrapper.addCallback(self._actorWrapperStateChanged) self._actorWrapperStateChanged() def _makeDispatcher(self, connection): self.debugMsg("_makeDispatcher()") self.dispatcher = ActorDispatcher( connection = connection, name = self._dictName, # name of keyword dictionary ) # initialize a command queue self.cmdQueue = DispatcherCmdQueue(self.dispatcher) @property def actor(self): """!Return the actor (in this case, the mirror controller) """ return self.actorWrapper.actor @property def userPort(self): """!Return the actor port, if known, else None """ return self.actorWrapper.userPort @property def isReady(self): """!Return True if the actor has connected to the fake hardware controller """ return self.actorWrapper.isReady and self.dispatcher is not None and self.dispatcher.connection.isConnected @property def isDone(self): """!Return True if the actor and fake hardware controller are fully disconnected """ return self.actorWrapper.isDone and self.dispatcher is not None and self.dispatcher.connection.isDisconnected @property def isFailing(self): """!Return True if there is a failure """ return self.actorWrapper.didFail or (self.dispatcher is not None and self.dispatcher.connection.didFail) def queueCmd(self, cmdStr, timeLim=0, timeLimKeyVar=None, timeLimKeyInd=0, keyVars=None, callFunc=None, callCodes=":"): """!add command to queue, dispatch when ready @warning error handling is determined by callCodes; for details, see the documentation for the returned deferred below @param[in] cmdStr a command string @param[in] timeLim maximum time before command expires, in sec; 0 for no limit @param[in] timeLimKeyVar a KeyVar specifying a delta-time by which the command must finish @param[in] timeLimKeyInd the index of the time limit value in timeLimKeyVar; defaults to 0; ignored if timeLimKeyVar is None. @param[in] keyVars a sequence of 0 or more keyword variables to monitor for this command. Any data for those variables that arrives IN RESPONSE TO THIS COMMAND is saved and can be retrieved using cmdVar.getKeyVarData or cmdVar.getLastKeyVarData. @param[in] callFunc receives one arguement the CmdVar @param[in] callCodes a string of message codes that will result in calling callFunc; common values include ":"=success, "F"=failure and ">"=queued see opscore.actor.keyvar for all call codes. Common use cases: - To call callFunc only when the command succeeds, use callCodes=":" (the default); if the command fails callFunc is not called. - To call callFunc every time the cmdVar calls back, while running successfully, specify callCodes=""DIW:>". Again, if the command fails callFunc is not called. - To test a command you expect to fail, specify callCodes=":F!" and have callFunc assert cmdVar.didFail @return two items: - deferred: a Twisted Deferred: - errorback is called if: - the cmdVar fails (unless callCodes includes "F") - callFunc raises an exception - otherwise callback is called when the command is done and callFunc did not raise an exception - cmdVar: the CmdVar for the command """ cmdVar = CmdVar( actor = self._dictName, cmdStr = cmdStr, timeLim = timeLim, timeLimKeyVar = timeLimKeyVar, timeLimKeyInd = timeLimKeyInd, keyVars = keyVars, ) cmdWrapper = CmdWrapper(cmdVar=cmdVar, callFunc=callFunc, callCodes=callCodes) self.cmdQueue.addCmd(cmdWrapper) return (cmdWrapper.deferred, cmdVar) def _actorWrapperStateChanged(self, dumArg=None): """!Called when the device wrapper changes state """ if self.actorWrapper.isReady and not self.dispatcher: connection = TCPConnection( host = 'localhost', port = self.actorWrapper.userPort, readLines = True, name = "mirrorCtrlConn", ) self._makeDispatcher(connection) connection.addStateCallback(self._stateChanged) if self._readCallback: connection.addReadCallback(self._readCallback) connection.connect() self._stateChanged() def _basicClose(self): """!Close dispatcher and actor """ if self.dispatcher: self.dispatcher.disconnect() self.actorWrapper.close()
class DispatcherWrapper(BaseWrapper): """!A wrapper for an opscore.ActorDispatcher talking to an wrapped actor This wrapper is responsible for starting and stopping everything: - It builds an actor dispatcher when the actor wrapper is ready - It stops the actor wrapper and actor dispatcher on close() Public attributes include: - actorWrapper: the actor wrapper (twistedActor.ActorWrapper) - dispatcher: the actor dispatcher (twistedActor.ActorDispatcher); None until ready - readyDeferred: called when the dispatcher is ready (for tracking closure use the Deferred returned by the close method, or stateCallback). """ def __init__( self, actorWrapper, dictName, name="", readCallback=None, stateCallback=None, debug=False, ): """!Construct a DispatcherWrapper that manages everything @param[in] actorWrapper actor wrapper (twistedActor.ActorWrapper); must be starting up or ready @param[in] dictName name of actor keyword dictionary @param[in] name a name to use for messages @param[in] readCallback function to call when the actor dispatcher has data to read @param[in] stateCallback function to call when connection state of of any socket changes; receives one argument: this actor wrapper @param[in] debug print debug messages to stdout? """ BaseWrapper.__init__( self, name=name, stateCallback=stateCallback, callNow=False, debug=debug, ) self.actorWrapper = actorWrapper self._dictName = dictName self._readCallback = readCallback self.dispatcher = None # the ActorDispatcher, once it's built self.actorWrapper.addCallback(self._actorWrapperStateChanged) self._actorWrapperStateChanged() def _makeDispatcher(self, connection): self.debugMsg("_makeDispatcher()") self.dispatcher = ActorDispatcher( connection=connection, name=self._dictName, # name of keyword dictionary ) # initialize a command queue self.cmdQueue = DispatcherCmdQueue(self.dispatcher) @property def actor(self): """!Return the actor (in this case, the mirror controller) """ return self.actorWrapper.actor @property def userPort(self): """!Return the actor port, if known, else None """ return self.actorWrapper.userPort @property def isReady(self): """!Return True if the actor has connected to the fake hardware controller """ return self.actorWrapper.isReady and self.dispatcher is not None and self.dispatcher.connection.isConnected @property def isDone(self): """!Return True if the actor and fake hardware controller are fully disconnected """ return self.actorWrapper.isDone and self.dispatcher is not None and self.dispatcher.connection.isDisconnected @property def isFailing(self): """!Return True if there is a failure """ return self.actorWrapper.didFail or ( self.dispatcher is not None and self.dispatcher.connection.didFail) def queueCmd(self, cmdStr, timeLim=0, timeLimKeyVar=None, timeLimKeyInd=0, keyVars=None, callFunc=None, callCodes=":"): """!add command to queue, dispatch when ready @warning error handling is determined by callCodes; for details, see the documentation for the returned deferred below @param[in] cmdStr a command string @param[in] timeLim maximum time before command expires, in sec; 0 for no limit @param[in] timeLimKeyVar a KeyVar specifying a delta-time by which the command must finish @param[in] timeLimKeyInd the index of the time limit value in timeLimKeyVar; defaults to 0; ignored if timeLimKeyVar is None. @param[in] keyVars a sequence of 0 or more keyword variables to monitor for this command. Any data for those variables that arrives IN RESPONSE TO THIS COMMAND is saved and can be retrieved using cmdVar.getKeyVarData or cmdVar.getLastKeyVarData. @param[in] callFunc receives one arguement the CmdVar @param[in] callCodes a string of message codes that will result in calling callFunc; common values include ":"=success, "F"=failure and ">"=queued see opscore.actor.keyvar for all call codes. Common use cases: - To call callFunc only when the command succeeds, use callCodes=":" (the default); if the command fails callFunc is not called. - To call callFunc every time the cmdVar calls back, while running successfully, specify callCodes=""DIW:>". Again, if the command fails callFunc is not called. - To test a command you expect to fail, specify callCodes=":F!" and have callFunc assert cmdVar.didFail @return two items: - deferred: a Twisted Deferred: - errorback is called if: - the cmdVar fails (unless callCodes includes "F") - callFunc raises an exception - otherwise callback is called when the command is done and callFunc did not raise an exception - cmdVar: the CmdVar for the command """ cmdVar = CmdVar( actor=self._dictName, cmdStr=cmdStr, timeLim=timeLim, timeLimKeyVar=timeLimKeyVar, timeLimKeyInd=timeLimKeyInd, keyVars=keyVars, ) cmdWrapper = CmdWrapper(cmdVar=cmdVar, callFunc=callFunc, callCodes=callCodes) self.cmdQueue.addCmd(cmdWrapper) return (cmdWrapper.deferred, cmdVar) def _actorWrapperStateChanged(self, dumArg=None): """!Called when the device wrapper changes state """ if self.actorWrapper.isReady and not self.dispatcher: connection = TCPConnection( host='localhost', port=self.actorWrapper.userPort, readLines=True, name="mirrorCtrlConn", ) self._makeDispatcher(connection) connection.addStateCallback(self._stateChanged) if self._readCallback: connection.addReadCallback(self._readCallback) connection.connect() self._stateChanged() def _basicClose(self): """!Close dispatcher and actor """ if self.dispatcher: self.dispatcher.disconnect() self.actorWrapper.close()