def run_maestral_daemon(config_name="maestral", run=True, log_to_stdout=False): """ Wraps :class:`maestral.main.Maestral` as Pyro daemon object, creates a new instance and start Pyro's event loop to listen for requests on a unix domain socket. This call will block until the event loop shuts down. This command will return silently if the daemon is already running. :param str config_name: The name of the Maestral configuration to use. :param bool run: If ``True``, start syncing automatically. Defaults to ``True``. :param bool log_to_stdout: If ``True``, write logs to stdout. Defaults to ``False``. """ from maestral.main import Maestral sock_name = sockpath_for_config(config_name) pid_name = pidpath_for_config(config_name) lockfile = PIDLockFile(pid_name) # acquire PID lock file try: lockfile.acquire(timeout=1) except AlreadyLocked: if is_pidfile_stale(lockfile): lockfile.break_lock() else: logger.debug(f"Maestral already running") return logger.debug(f"Starting Maestral daemon on socket '{sock_name}'") try: # clean up old socket, create new one try: os.remove(sock_name) except FileNotFoundError: pass daemon = Daemon(unixsocket=sock_name) # start Maestral as Pyro server ExposedMaestral = expose(Maestral) # mark stop_sync and shutdown_daemon as oneway methods # so that they don't block on call ExposedMaestral.stop_sync = oneway(ExposedMaestral.stop_sync) ExposedMaestral.shutdown_pyro_daemon = oneway( ExposedMaestral.shutdown_pyro_daemon) m = ExposedMaestral(config_name, run=run, log_to_stdout=log_to_stdout) daemon.register(m, f"maestral.{config_name}") daemon.requestLoop(loopCondition=m._loop_condition) daemon.close() except Exception: traceback.print_exc() finally: # remove PID lock lockfile.release()
def main(): config = configparser.ConfigParser() # does not throw an error, just returns the empty set if the file doesn't exist config.read(CONFIG.BASEPATH + '/config/iGrill_config.ini') loglevel = config.get("Logging", "LogLevel", fallback="Error") logfile = config.get("Logging", "LogFile", fallback="") parser = argparse.ArgumentParser( description='Runs a thread to control the buzzer') parser.add_argument('-l', '--log-level', action='store', dest='log_level', default=loglevel, help='Set log level, default: \'' + loglevel + '\'') parser.add_argument('-d', '--log-destination', action='store', dest='log_destination', default=logfile, help='Set log destination (file), default: \'' + logfile + '\'') options = parser.parse_args() SetupLog(options.log_level, options.log_destination) daemon = Daemon(host=BUZZ.DAEMON.PYRO_HOST, port=BUZZ.DAEMON.PYRO_PORT) buzzObj = Buzzer(daemon) uri = daemon.register(buzzObj, objectId=BUZZ.DAEMON.PYRO_OBJECT_ID) logging.debug(uri) daemon.requestLoop() logging.debug('exited requestLoop') daemon.shutdown() daemon.close() logging.debug('daemon closed') sys.exit(buzzObj.ExitCode())
def main(): gui = PyroGUI() # create a pyro daemon with object daemon = Daemon() obj = MessagePrinter(gui) uri = daemon.register(obj, "pyrogui.message") gui.add_message("Pyro server started. Not using threads.") gui.add_message("Use the command line client to send messages.") urimsg = "Pyro object uri = {0}".format(uri) gui.add_message(urimsg) print(urimsg) # add a Pyro event callback to the gui's mainloop gui.install_pyro_event_callback(daemon) # enter the mainloop gui.mainloop()
from Pyro5.api import locate_ns, Daemon, type_meta, Proxy from resources import LaserPrinter, MatrixPrinter, PhotoPrinter, TapeStorage, DiskStorage, Telephone, Faxmachine # register various objects with some metadata describing their resource class ns = locate_ns() d = Daemon() uri = d.register(LaserPrinter) ns.register("example.resource.laserprinter", uri, metadata=type_meta(LaserPrinter) | {"resource:printer", "performance:fast"}) uri = d.register(MatrixPrinter) ns.register("example.resource.matrixprinter", uri, metadata=type_meta(MatrixPrinter) | {"resource:printer", "performance:slow"}) uri = d.register(PhotoPrinter) ns.register("example.resource.photoprinter", uri, metadata=type_meta(PhotoPrinter) | {"resource:printer", "performance:slow"}) uri = d.register(TapeStorage) ns.register("example.resource.tapestorage", uri, metadata=type_meta(TapeStorage) | {"resource:storage", "performance:slow"}) uri = d.register(DiskStorage) ns.register("example.resource.diskstorage", uri, metadata=type_meta(DiskStorage)
import time from Pyro5.api import expose, locate_ns, Daemon, config @expose class TimeoutServer(object): def delay(self, amount): print("sleeping %d" % amount) time.sleep(amount) print("done.") return "slept %d seconds" % amount config.COMMTIMEOUT = 0 # the server won't be using timeouts ns = locate_ns() daemon = Daemon() daemon2 = Daemon() obj = TimeoutServer() obj2 = TimeoutServer() uri = daemon.register(obj) uri2 = daemon2.register(obj2) ns.register("example.timeout", uri) ns.register("example.timeout.frozendaemon", uri2) print("Server ready.") # Note that we're only starting one of the 2 daemons. # daemon2 is not started, to simulate connection timeouts. daemon.requestLoop()
help="hostname to bind server on") parser.add_option("-p", "--port", dest="port", type="int", default=0, help="port to bind server on (0=random)") parser.add_option("-u", "--unixsocket", help="Unix domain socket name to bind server on") parser.add_option("-s", "--storage", dest="storage", type="choice", choices=["sqlite", "memory"], default="sqlite", help="storage type (default=%default)") options, args = parser.parse_args() make_messagebus.storagetype = options.storage daemon = Daemon(host=options.host, port=options.port, unixsocket=options.unixsocket) uri = daemon.register(MessageBus) print("Pyro Message Bus.") print(" uri =", uri) ns = locate_ns() ns.register(PYRO_MSGBUS_NAME, uri) print(" name =", PYRO_MSGBUS_NAME) print("Server running, storage is {}.".format(make_messagebus.storagetype)) daemon.requestLoop()
def run_maestral_daemon(config_name='maestral', run=True, log_to_stdout=False): """ Wraps :class:`maestral.main.Maestral` as Pyro daemon object, creates a new instance and start Pyro's event loop to listen for requests on a unix domain socket. This call will block until the event loop shuts down. This command will return silently if the daemon is already running. :param str config_name: The name of the Maestral configuration to use. :param bool run: If ``True``, start syncing automatically. Defaults to ``True``. :param bool log_to_stdout: If ``True``, write logs to stdout. Defaults to ``False``. """ import threading from maestral.main import Maestral sock_name = sockpath_for_config(config_name) pid_name = pidpath_for_config(config_name) lockfile = PIDLockFile(pid_name) if threading.current_thread() is threading.main_thread(): signal.signal(signal.SIGTERM, _sigterm_handler) # acquire PID lock file try: lockfile.acquire(timeout=1) except (AlreadyLocked, LockTimeout): if is_pidfile_stale(lockfile): lockfile.break_lock() else: logger.debug(f'Maestral already running') return # Nice ourselves give other processes priority. We will likely only # have significant CPU usage in case of many concurrent downloads. os.nice(10) logger.debug(f'Starting Maestral daemon on socket "{sock_name}"') try: # clean up old socket try: os.remove(sock_name) except FileNotFoundError: pass daemon = Daemon(unixsocket=sock_name) # start Maestral as Pyro server ExposedMaestral = expose(Maestral) # mark stop_sync and shutdown_daemon as one way # methods so that they don't block on call ExposedMaestral.stop_sync = oneway(ExposedMaestral.stop_sync) ExposedMaestral.pause_sync = oneway(ExposedMaestral.pause_sync) ExposedMaestral.shutdown_pyro_daemon = oneway( ExposedMaestral.shutdown_pyro_daemon) m = ExposedMaestral(config_name, run=run, log_to_stdout=log_to_stdout) daemon.register(m, f'maestral.{config_name}') daemon.requestLoop(loopCondition=m._loop_condition) daemon.close() except Exception: traceback.print_exc() except (KeyboardInterrupt, SystemExit): logger.info('Received system exit') sys.exit(0) finally: lockfile.release()
#!/usr/bin/env python3 """Daemon.""" from Pyro5.api import Daemon, expose, behavior, serve, current_context, oneway from gpio_led import LEDPanel @expose @behavior(instance_mode="single") class Photobooth(object): """Photobooth daemon.""" def __init__(self): self.ledPanelCtl = None @oneway def ledCtl(self, action, resume, brightness, kwargs): if not self.ledPanelCtl: self.ledPanelCtl = LEDPanel().get_effects() self.ledPanelCtl.abort() self.ledPanelCtl.run(action, resume, brightness, kwargs) if __name__ == "__main__": daemon = Daemon(host="localhost", port=9090) uri = daemon.register(Photobooth, 'ledpanel.control') daemon.requestLoop()
# create our own socket pair (server-client sockets that are already connected) sock1, sock2 = socket.socketpair() class Echo(object): @expose def echo(self, message): print("server got message: ", message) return "thank you" # create a daemon with some Pyro objectrunning on our custom server socket daemon = Daemon(connected_socket=sock1) daemon.register(Echo, "echo") print("(Pyro daemon running on", daemon.locationStr, ")\n") daemonthread = threading.Thread(target=daemon.requestLoop) daemonthread.daemon = True daemonthread.start() # create a client running on the client socket with Proxy("echo", connected_socket=sock2) as p: reply = p.echo("hello!") print("client got reply:", reply) reply = p.echo("hello again!") print("client got reply:", reply) with Proxy("echo", connected_socket=sock2) as p: reply = p.echo("hello2!") print("client got reply:", reply)
def main(log_to_file=True): import pkg_resources version = pkg_resources.require('humidifier-controller')[0].version print('Starting Humidifier Controller Server, version: ' + version) config.SERVERTYPE = 'multiplex' daemon = Daemon() def start_client_logger(): from threading import Thread t = Thread(target=Logger, kwargs={'log_to_file': log_to_file}, daemon=True) t.start() return t def signal_handler(signo, frame): if daemon != None: daemon.transportServer.shutting_down = True print(f'Shutting down gracefully exit code: {signo}') daemon.shutdown() from threading import enumerate logger_threads = [ thread for thread in enumerate() if isinstance(thread, Logger) ] for logger_thread in logger_threads: print("Stopping {}.".format(logger_thread)) logger_thread.stop() sys.exit(1) import signal for sig in ('TERM', 'HUP', 'INT'): signal.signal(getattr(signal, 'SIG' + sig), signal_handler) nameserverDaemon = None try: nameserverUri, nameserverDaemon, broadcastServer = start_ns() assert broadcastServer is not None, "expect a broadcast server to be created" print("got a Nameserver, uri=%s" % nameserverUri) except OSError: print('Pyro nameserver already running. No idea who started it.') if (nameserverDaemon == None): with locate_ns() as ns: try: ns.lookup('serial_server.serial_connection') print("Serial server is already registered. Aborting.") return 0 except: pass serial_connection = SerialConnection(baudrate='9600') serial_connection.set_settings(serial_connection.read_settings()) serial_connection.post_message('\0') serial_uri = daemon.register(serial_connection) if (nameserverDaemon == None): with locate_ns() as ns: ns.register('serial_server.serial_connection', serial_uri) else: nameserverDaemon.nameserver.register('serial_server.serial_connection', serial_uri) daemon.combine(nameserverDaemon) daemon.combine(broadcastServer) print('Serial connection registered.') start_client_logger() daemon.requestLoop()
class Test_KasaDaemon(unittest.TestCase): def setUp(self): self.m_daemon = Daemon(host=KASA.DAEMON.PYRO_HOST, port=KASA.DAEMON.PYRO_PORT) # This must be scoped oddly. Daemon uses sockets so we don't want to mock the socket # object untill the daemon is setup. with mock.patch('pygrill.kasa.kasa_daemon.socket.socket') as mockitem: self.m_mock_inst = mockitem.return_value self.m_mock_inst.recvfrom.return_value = [kasa_daemon.Encrypt( TEST.KASA.DAEMON.DISCOVER_RSP), ['192.168.0.0', 9999]] self.m_mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader( TEST.KASA.DAEMON.DISCOVER_RSP) self.m_kasaDaemon = kasa_daemon.Kasa(self.m_daemon) self.m_daemon.register( self.m_kasaDaemon, objectId=KASA.DAEMON.PYRO_OBJECT_ID) def tearDown(self): self.m_kasaDaemon.Exit() self.m_daemon.close() self.assertEqual(self.m_kasaDaemon.ExitCode(), 0) def test_Power(self): # Since the above mock is out of scope, we must create a new mock here with mock.patch('pygrill.kasa.kasa_daemon.socket.socket') as mockitem: mock_inst = mockitem.return_value mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader( TEST.KASA.DAEMON.OFF_ON_NO_ERROR_RSP) self.m_kasaDaemon.TurnPlugOn() self.assertListEqual(self.m_kasaDaemon.GetErrors(), list()) mock_inst.send.assert_called_with( kasa_daemon.EncryptWithHeader(KASA.DAEMON.JSON_PLUG_ON)) mock_inst.reset_mock() mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader( TEST.KASA.DAEMON.ON_ON_NO_ERROR_RSP) self.m_kasaDaemon.TurnPlugOn() self.assertListEqual(self.m_kasaDaemon.GetErrors(), list()) mock_inst.send.assert_called_with( kasa_daemon.EncryptWithHeader(KASA.DAEMON.JSON_COUNTDOWN_DELETE_AND_RUN)) mock_inst.reset_mock() mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader( TEST.KASA.DAEMON.ON_OFF_NO_ERROR_RSP) self.m_kasaDaemon.TurnPlugOff() self.assertListEqual(self.m_kasaDaemon.GetErrors(), list()) mock_inst.send.assert_called_with( kasa_daemon.EncryptWithHeader(KASA.DAEMON.JSON_PLUG_OFF)) mock_inst.reset_mock() mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader( TEST.KASA.DAEMON.OFF_OFF_NO_ERROR_RSP) self.m_kasaDaemon.TurnPlugOff() self.assertListEqual(self.m_kasaDaemon.GetErrors(), list()) mock_inst.send.assert_called_with( kasa_daemon.EncryptWithHeader(KASA.DAEMON.JSON_COUNTDOWN_DELETE)) mock_inst.reset_mock() mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader( TEST.KASA.DAEMON.OFF_ERROR_RSP) self.m_kasaDaemon.TurnPlugOff() mock_inst.send.assert_called_with( kasa_daemon.EncryptWithHeader(KASA.DAEMON.JSON_COUNTDOWN_DELETE)) resp = list() resp.append(kasa_daemon.Decrypt( kasa_daemon.Encrypt(TEST.KASA.DAEMON.OFF_ERROR_RSP))) resp.append(kasa_daemon.Decrypt( kasa_daemon.Encrypt(TEST.KASA.DAEMON.OFF_ERROR_RSP))) print(self.m_kasaDaemon.GetErrors()) self.assertListEqual(self.m_kasaDaemon.GetErrors(), resp) mock_inst.send.assert_called() mock_inst.reset_mock() self.assertEqual(self.m_kasaDaemon.GetActive(), False) def test_IP(self): self.assertEqual(self.m_kasaDaemon.GetIP(), "192.168.0.0")
# initialize the logger so you can see what is happening with the callback exception message: logging.basicConfig(stream=sys.stderr, format="[%(asctime)s,%(name)s,%(levelname)s] %(message)s") log = logging.getLogger("Pyro5") log.setLevel(logging.WARNING) class CallbackHandler(object): @expose @callback def call2(self): print("\n\ncallback 2 received from server!") print("going to crash - but you will see the exception printed here too:") daemon = Daemon() callback = CallbackHandler() daemon.register(callback) homeBroker = Proxy("PYRONAME:home.broker.server") # homeBroker.doCallback(callback) # this is a oneway call, so we can continue right away print("waiting for callbacks to arrive...") print("(ctrl-c/break the program once it's done)") def printMenu(): print("-----------HOME BROKER-----------") print("1) Adicionar ação às minhas cotações") print("2) Remover ação às minhas cotações") print("3) Ver minha lista de cotações") print("4) Comprar ação") print("5) Vender ação")
def run(self): daemon = Daemon() obj = MessagePrinter(self.gui) self.uri = daemon.register(obj, "pyrogui.message2") self.started.set() daemon.requestLoop()
for t in topics: self.message_counter[t] = 0 self.last_message[t] = None def consume_message(self, topic, message): self.message_counter[topic] += 1 self.last_message[topic] = message def clear_screen(): os.system(['clear', 'cls'][os.name == 'nt']) subber = Subber() d = Daemon() d.register(subber) daemon_thread = threading.Thread(target=d.requestLoop) daemon_thread.daemon = True daemon_thread.start() # mass subscribe to all available topics topics = list(sorted(subber.bus.topics())) subber.init_counters(topics) for t in topics: subber.bus.subscribe(t, subber) # show a table of the active topics on the bus while True: clear_screen() print(time.ctime(), "-- active topics on the messagebus:") print("{:20} : {:5} {} {}".format("topic", "count", "last_recv", "last message data"))
# object, we could skip all this and just register as usual. # That works because the proxy, when reconnecting, will do a new nameserver lookup # and receive the new object uri back. This REQUIRES: # - clients will never connect using a PYRO-uri # - client proxy._pyroBind() is never called # BUT for sake of example, and because we really cannot guarantee the above, # here we go for the safe route and reuse our previous object id. ns = locate_ns() try: existing = ns.lookup("remote") print("Object still exists in Name Server with id: %s" % existing.object) print("Previous daemon socket port: %d" % existing.port) # start the daemon on the previous port daemon = Daemon(port=existing.port) # register the object in the daemon with the old objectId daemon.register(TestClass, objectId=existing.object) except Pyro5.errors.NamingError: print("There was no previous registration in the name server.") # just start a new daemon on a random port daemon = Daemon() # register the object in the daemon and let it get a new objectId # also need to register in name server because it's not there yet. uri = daemon.register(TestClass) ns.register("remote2", uri) print("Server started.") daemon.requestLoop() # note: we are not removing the name server registration when terminating!