def __init__(self, host=None, port=0): if host is None: host=Pyro.config.HOST if Pyro.config.SERVERTYPE=="thread": self.transportServer=SocketServer_Threadpool(self, host, port, Pyro.config.COMMTIMEOUT) elif Pyro.config.SERVERTYPE=="select": self.transportServer=SocketServer_Select(self, host, port, Pyro.config.COMMTIMEOUT) else: raise Pyro.errors.PyroError("invalid server type '%s'" % Pyro.config.SERVERTYPE) self.locationStr=self.transportServer.locationStr log.debug("created daemon on %s", self.locationStr) self.serializer=Pyro.util.Serializer() pyroObject=DaemonObject(self) pyroObject._pyroId=Pyro.constants.DAEMON_NAME self.objectsById={pyroObject._pyroId: pyroObject} self.__mustshutdown=False self.__loopstopped=threadutil.Event() self.__loopstopped.set()
def __init__(self, host=None, port=0): if host is None: host = Pyro.config.HOST if Pyro.config.SERVERTYPE == "thread": self.transportServer = SocketServer_Threadpool( self, host, port, Pyro.config.COMMTIMEOUT) elif Pyro.config.SERVERTYPE == "select": self.transportServer = SocketServer_Select(self, host, port, Pyro.config.COMMTIMEOUT) else: raise Pyro.errors.PyroError("invalid server type '%s'" % Pyro.config.SERVERTYPE) self.locationStr = self.transportServer.locationStr log.debug("created daemon on %s", self.locationStr) self.serializer = Pyro.util.Serializer() pyroObject = DaemonObject(self) pyroObject._pyroId = Pyro.constants.DAEMON_NAME self.objectsById = {pyroObject._pyroId: pyroObject} self.__mustshutdown = False self.__loopstopped = threadutil.Event() self.__loopstopped.set()
class Daemon(object): """ Pyro daemon. Contains server side logic and dispatches incoming remote method calls to the appropriate objects. """ def __init__(self, host=None, port=0): if host is None: host=Pyro.config.HOST if Pyro.config.SERVERTYPE=="thread": self.transportServer=SocketServer_Threadpool(self, host, port, Pyro.config.COMMTIMEOUT) elif Pyro.config.SERVERTYPE=="select": self.transportServer=SocketServer_Select(self, host, port, Pyro.config.COMMTIMEOUT) else: raise Pyro.errors.PyroError("invalid server type '%s'" % Pyro.config.SERVERTYPE) self.locationStr=self.transportServer.locationStr log.debug("created daemon on %s", self.locationStr) self.serializer=Pyro.util.Serializer() pyroObject=DaemonObject(self) pyroObject._pyroId=Pyro.constants.DAEMON_NAME self.objectsById={pyroObject._pyroId: pyroObject} self.__mustshutdown=False self.__loopstopped=threadutil.Event() self.__loopstopped.set() def fileno(self): return self.transportServer.fileno() @property def sock(self): return self.transportServer.sock def requestLoop(self, loopCondition=lambda:True): """ Goes in a loop to service incoming requests, until someone breaks this or calls shutdown from another thread. """ self.__mustshutdown=False log.info("daemon %s entering requestloop", self.locationStr) try: self.__loopstopped.clear() condition=lambda: not self.__mustshutdown and loopCondition() self.transportServer.requestLoop(loopCondition=condition) finally: self.__loopstopped.set() log.debug("daemon exits requestloop") def handleRequests(self): return self.transportServer.handleRequests() def shutdown(self): """Cleanly terminate a deamon that is running in the requestloop. It must be running in a different thread, or this method will deadlock.""" log.debug("daemon shutting down") self.__mustshutdown=True self.pingConnection() time.sleep(0.05) self.close() self.__loopstopped.wait() log.info("daemon %s shut down", self.locationStr) def pingConnection(self): """bit of a hack to trigger a blocking server to get out of the loop, useful at clean shutdowns""" self.transportServer.pingConnection() def handshake(self, conn): if not Pyro.config.CONNECTHANDSHAKE: return True """Perform connection handshake with new clients""" header=conn.recv(MessageFactory.HEADERSIZE) msgType,flags,dataLen=MessageFactory.parseMessageHeader(header) #@UnusedVariable (pydev) if msgType!=MessageFactory.MSG_CONNECT: err="expected MSG_CONNECT message, got %d" % msgType log.warn(err) raise Pyro.errors.ProtocolError(err) if dataLen>0: conn.recv(dataLen) # read away any trailing data (unused at the moment) msg=MessageFactory.createMessage(MessageFactory.MSG_CONNECTOK,None,0) conn.send(msg) return True def handleRequest(self, conn): """ Handle incoming Pyro request. Catches any exception that may occur and wraps it in a reply to the calling side, as to not make this server side loop terminate due to exceptions caused by remote invocations. """ flags=0 try: header=conn.recv(MessageFactory.HEADERSIZE) msgType,flags,dataLen=MessageFactory.parseMessageHeader(header) if msgType!=MessageFactory.MSG_INVOKE: err="handlerequest: invalid msg type %d received" % msgType log.warn(err) raise Pyro.errors.ProtocolError(err) data=conn.recv(dataLen) objId, method, vargs, kwargs=self.serializer.deserialize( data,compressed=flags & MessageFactory.FLAGS_COMPRESSED) obj=self.objectsById.get(objId) if obj is not None: if kwargs and sys.version_info<(2,6,5) and os.name!="java": # Python before 2.6.5 doesn't accept unicode keyword arguments kwargs = dict((str(k),kwargs[k]) for k in kwargs) log.debug("calling %s.%s",obj.__class__.__name__,method) obj=Pyro.util.resolveDottedAttribute(obj,method,Pyro.config.DOTTEDNAMES) if flags & MessageFactory.FLAGS_ONEWAY and Pyro.config.ONEWAY_THREADED: # oneway call to be run inside its own thread thread=threadutil.Thread(target=obj, args=vargs, kwargs=kwargs) thread.setDaemon(True) thread.start() else: data=obj(*vargs,**kwargs) # this is the actual method call to the Pyro object else: log.debug("unknown object requested: %s",objId) raise Pyro.errors.DaemonError("unknown object") if flags & MessageFactory.FLAGS_ONEWAY: return # oneway call, don't send a response else: data,compressed=self.serializer.serialize(data,compress=Pyro.config.COMPRESSION) flags=0 if compressed: flags |= MessageFactory.FLAGS_COMPRESSED msg=MessageFactory.createMessage(MessageFactory.MSG_RESULT, data, flags) del data conn.send(msg) except Pyro.errors.CommunicationError,x: # communication errors are not handled here (including TimeoutError) raise except Exception,x: # all other errors are caught log.debug("Exception occurred while handling request: %s",x) if not flags & MessageFactory.FLAGS_ONEWAY: # only return the error to the client if it wasn't a oneway call tblines=Pyro.util.formatTraceback(detailed=Pyro.config.DETAILED_TRACEBACK) self.sendExceptionResponse(conn, x, tblines)
class Daemon(object): """ Pyro daemon. Contains server side logic and dispatches incoming remote method calls to the appropriate objects. """ def __init__(self, host=None, port=0): if host is None: host = Pyro.config.HOST if Pyro.config.SERVERTYPE == "thread": self.transportServer = SocketServer_Threadpool( self, host, port, Pyro.config.COMMTIMEOUT) elif Pyro.config.SERVERTYPE == "select": self.transportServer = SocketServer_Select(self, host, port, Pyro.config.COMMTIMEOUT) else: raise Pyro.errors.PyroError("invalid server type '%s'" % Pyro.config.SERVERTYPE) self.locationStr = self.transportServer.locationStr log.debug("created daemon on %s", self.locationStr) self.serializer = Pyro.util.Serializer() pyroObject = DaemonObject(self) pyroObject._pyroId = Pyro.constants.DAEMON_NAME self.objectsById = {pyroObject._pyroId: pyroObject} self.__mustshutdown = False self.__loopstopped = threadutil.Event() self.__loopstopped.set() def fileno(self): return self.transportServer.fileno() @property def sock(self): return self.transportServer.sock def requestLoop(self, loopCondition=lambda: True): """ Goes in a loop to service incoming requests, until someone breaks this or calls shutdown from another thread. """ self.__mustshutdown = False log.info("daemon %s entering requestloop", self.locationStr) try: self.__loopstopped.clear() condition = lambda: not self.__mustshutdown and loopCondition() self.transportServer.requestLoop(loopCondition=condition) finally: self.__loopstopped.set() log.debug("daemon exits requestloop") def handleRequests(self): return self.transportServer.handleRequests() def shutdown(self): """Cleanly terminate a deamon that is running in the requestloop. It must be running in a different thread, or this method will deadlock.""" log.debug("daemon shutting down") self.__mustshutdown = True self.pingConnection() time.sleep(0.05) self.close() self.__loopstopped.wait() log.info("daemon %s shut down", self.locationStr) def pingConnection(self): """bit of a hack to trigger a blocking server to get out of the loop, useful at clean shutdowns""" self.transportServer.pingConnection() def handshake(self, conn): if not Pyro.config.CONNECTHANDSHAKE: return True """Perform connection handshake with new clients""" header = conn.recv(MessageFactory.HEADERSIZE) msgType, flags, dataLen = MessageFactory.parseMessageHeader( header) #@UnusedVariable (pydev) if msgType != MessageFactory.MSG_CONNECT: err = "expected MSG_CONNECT message, got %d" % msgType log.warn(err) raise Pyro.errors.ProtocolError(err) if dataLen > 0: conn.recv( dataLen) # read away any trailing data (unused at the moment) msg = MessageFactory.createMessage(MessageFactory.MSG_CONNECTOK, None, 0) conn.send(msg) return True def handleRequest(self, conn): """ Handle incoming Pyro request. Catches any exception that may occur and wraps it in a reply to the calling side, as to not make this server side loop terminate due to exceptions caused by remote invocations. """ flags = 0 try: header = conn.recv(MessageFactory.HEADERSIZE) msgType, flags, dataLen = MessageFactory.parseMessageHeader(header) if msgType != MessageFactory.MSG_INVOKE: err = "handlerequest: invalid msg type %d received" % msgType log.warn(err) raise Pyro.errors.ProtocolError(err) data = conn.recv(dataLen) objId, method, vargs, kwargs = self.serializer.deserialize( data, compressed=flags & MessageFactory.FLAGS_COMPRESSED) obj = self.objectsById.get(objId) if obj is not None: if kwargs and sys.version_info < (2, 6, 5) and os.name != "java": # Python before 2.6.5 doesn't accept unicode keyword arguments kwargs = dict((str(k), kwargs[k]) for k in kwargs) log.debug("calling %s.%s", obj.__class__.__name__, method) obj = Pyro.util.resolveDottedAttribute(obj, method, Pyro.config.DOTTEDNAMES) if flags & MessageFactory.FLAGS_ONEWAY and Pyro.config.ONEWAY_THREADED: # oneway call to be run inside its own thread thread = threadutil.Thread(target=obj, args=vargs, kwargs=kwargs) thread.setDaemon(True) thread.start() else: data = obj( *vargs, **kwargs ) # this is the actual method call to the Pyro object else: log.debug("unknown object requested: %s", objId) raise Pyro.errors.DaemonError("unknown object") if flags & MessageFactory.FLAGS_ONEWAY: return # oneway call, don't send a response else: data, compressed = self.serializer.serialize( data, compress=Pyro.config.COMPRESSION) flags = 0 if compressed: flags |= MessageFactory.FLAGS_COMPRESSED msg = MessageFactory.createMessage(MessageFactory.MSG_RESULT, data, flags) del data conn.send(msg) except Pyro.errors.CommunicationError, x: # communication errors are not handled here (including TimeoutError) raise except Exception, x: # all other errors are caught log.debug("Exception occurred while handling request: %s", x) if not flags & MessageFactory.FLAGS_ONEWAY: # only return the error to the client if it wasn't a oneway call tblines = Pyro.util.formatTraceback( detailed=Pyro.config.DETAILED_TRACEBACK) self.sendExceptionResponse(conn, x, tblines)