class Service(object): """A generic service class meant to be run in a process on its own and handle requests using RPC. """ def __init__(self, loop, name, path): """Create a service with a name.""" self.loop = loop self.name = name self.path = path self.logger = logbook.Logger(self.name) def signal_init(self): self.sigintwatcher = pyev.Signal(signal.SIGINT, self.loop, self._stop) self.sigintwatcher.start() self.sigtermwatcher = pyev.Signal(signal.SIGTERM, self.loop, self._terminate) self.sigtermwatcher.start() def _stop(self, watcher, events): self.stop(signal.SIGINT) def _terminate(self, watcher, events): self.terminate(signal.SIGTERM) def listen_init(self): """Setup the service to listen for clients.""" self.dispatcher = ObjectDispatch(self) self.factory = MsgPackProtocolFactory(self.dispatcher) self.server = UnixServer(self.loop, self.factory, self.path) self.server.start() def run(self): """Run the event loop.""" self.signal_init() self.listen_init() self.logger.info('starting') self.loop.start() @remote def stop(self, reason=None): """Shutdown the service with a reason.""" self.logger.info('stopping') self.loop.stop(pyev.EVBREAK_ALL) @remote def terminate(self, reason=None): """Terminate the service with a reason.""" self.logger.info('terminating') self.loop.unloop(pyev.EVUNLOOP_ALL)
def server_main(loop, path): """Run in the client after the fork.""" loop.fork() logger.debug('forked function') sigintwatcher = pyev.Signal( signal.SIGINT, loop, lambda watcher, events: logger.info('interrupt ignored')) sigintwatcher.start() sigtermwatcher = pyev.Signal(signal.SIGTERM, loop, server_stop) sigtermwatcher.start() adder = AdderService() dispatcher = ObjectDispatch(adder) pickle_factory = PickleProtocolFactory(dispatcher) pickle_server = UnixServer(loop, pickle_factory, path) pickle_server.start() msgpack_factory = MsgPackProtocolFactory(dispatcher) msgpack_server = UnixServer(loop, msgpack_factory, path + '_mp') msgpack_server.start() logger.debug('running server loop') import cProfile cProfile.runctx('loop.loop()', None, {'loop': loop}, 'server_profile') logger.debug('server unlooped')
def test_unix_server(self): factory = ProtocolFactory() factory.protocol = Protocol server = UnixServer(loop, factory, "bogus") server = None # path should be cleaned up as soon as garbage collected gc.collect() self.assertTrue(not os.path.exists("bogus"))
class TestUnixServer(unittest.TestCase): def setUp(self): self.factory = MockFactory() self.factory.protocol = MockProtocol self.path = fpath + "/test_socket" self.server = UnixServer(loop, self.factory, self.path) def tearDown(self): self.server.shutdown() self.server = None self.server = None self.factory = None gc.collect() def c_sock(self): csock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) csock.setblocking(False) return csock def c_connect(self, csock): csock.connect(self.path) def c_isconnected(self, csock, testmsg="testmsg"): (rlist, wlist, xlist) = select.select([], [csock], [], 0.0) if csock in wlist: try: csock.send(testmsg) return True except IOError as e: return False else: return False def test_start(self): self.server.start() csock = self.c_sock() self.c_connect(csock) loop.start(pyev.EVRUN_ONCE) self.assertTrue(self.c_isconnected(csock)) def test_stop(self): self.server.start() csock = self.c_sock() self.c_connect(csock) loop.start(pyev.EVRUN_ONCE) self.assertTrue(self.c_isconnected(csock)) self.server.stop() loop.start(pyev.EVRUN_ONCE) self.assertTrue(self.c_isconnected(csock)) csock.close() csock = None loop.start(pyev.EVRUN_NOWAIT) csock = self.c_sock() self.c_connect(csock) self.assertTrue(self.factory.builds == 1)
def server_main(loop, path): """Run in the client after the fork.""" loop.fork() logger.debug('forked function') sigintwatcher = pyev.Signal(signal.SIGINT, loop, lambda watcher, events: logger.info('interrupt ignored')) sigintwatcher.start() sigtermwatcher = pyev.Signal(signal.SIGTERM, loop, server_stop) sigtermwatcher.start() adder = AdderService() dispatcher = ObjectDispatch(adder) pickle_factory = PickleProtocolFactory(dispatcher) pickle_server = UnixServer(loop, pickle_factory, path) pickle_server.start() msgpack_factory = MsgPackProtocolFactory(dispatcher) msgpack_server = UnixServer(loop, msgpack_factory, path + '_mp') msgpack_server.start() logger.debug('running server loop') import cProfile cProfile.runctx('loop.loop()', None, {'loop':loop}, 'server_profile') logger.debug('server unlooped')
def setUp(self): self.factory = MockFactory() self.factory.protocol = MockProtocol self.path = fpath + "/test_socket" self.server = UnixServer(loop, self.factory, self.path)
def listen_init(self): """Setup the service to listen for clients.""" self.dispatcher = ObjectDispatch(self) self.factory = MsgPackProtocolFactory(self.dispatcher) self.server = UnixServer(self.loop, self.factory, self.path) self.server.start()