Exemplo n.º 1
0
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())
Exemplo n.º 2
0
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()
Exemplo n.º 3
0
 def setUp(self):
     self.m_daemon = Daemon(host=BUZZ.DAEMON.PYRO_HOST,
                            port=BUZZ.DAEMON.PYRO_PORT)
     with mock.patch('pygrill.board.buzzer_daemon.pigpio.pi') as mockitem:
         self.m_mock_inst = mockitem.return_value
         self.m_buzzDaemon = buzzer_daemon.Buzzer(self.m_daemon,
                                                  boardIn=SSRC.BOARD.REV_sD)
         self.m_daemon.register(self.m_buzzDaemon,
                                objectId=BUZZ.DAEMON.PYRO_OBJECT_ID)
Exemplo n.º 4
0
 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)
Exemplo n.º 5
0
def threadAlert(stock, homeBroker):
    global option, running, ordemFinalizada

    with Daemon() as daemon2:
        homeBroker._pyroClaimOwnership()

        callback = CallbackHandler()
        daemon2.register(callback)

        worker = homeBroker.createWorker(
            callback)  #Cria worker no servidor para verificar preço da ação
        worker.addStockToAlert(stock)
        print("Alerta criado com sucesso!")
        ordemFinalizada = 1
        daemon2.requestLoop(
            loopCondition=lambda: CallbackHandler.workdone != True)
        CallbackHandler.workdone = False
Exemplo n.º 6
0
def main(args):
    if len(args) != 3:
        print("usage: client.py <robotname> <robottype>")
        print("   type is one of: %s" % list(observers.keys()))
        return
    name = args[1]
    observertype = args[2]
    with Daemon() as daemon:
        observer = observers[observertype]()
        daemon.register(observer)
        gameserver = Proxy("PYRONAME:example.robotserver")
        robot = gameserver.register(name, observer)
        with robot:  # make sure it disconnects, before the daemon thread uses it later
            robot.emote("Hi there! I'm here to kick your ass")
        observer.robot = robot
        print("Pyro server registered on %s" % daemon.locationStr)
        daemon.requestLoop()
Exemplo n.º 7
0
def threadExecuteOrder(order, homeBroker):
    global option, running, ordemFinalizada

    with Daemon() as daemon1:
        homeBroker._pyroClaimOwnership()

        callback = CallbackHandler()
        daemon1.register(callback)

        worker = homeBroker.createWorker(
            callback)  #Cria worker no servidor para tentar executar a ordem
        worker.tryExecuteOrder(order)
        print("Ordem enviada com sucesso!")
        ordemFinalizada = 1
        daemon1.requestLoop(
            loopCondition=lambda: CallbackHandler.workdone != True)
        CallbackHandler.workdone = False
Exemplo n.º 8
0
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()
Exemplo n.º 9
0
 def testSerializePyroTypes(self):
     uri = URI("PYRO:obj@host:9999")
     ser = self.serializer.dumps(uri)
     uri2 = self.serializer.loads(ser)
     assert isinstance(uri2, URI)
     assert uri2 == uri
     proxy = Proxy("PYRO:obj@host:9999")
     proxy._pyroHandshake = "handshake"
     ser = self.serializer.dumps(proxy)
     proxy2 = self.serializer.loads(ser)
     assert isinstance(proxy2, Proxy)
     assert proxy2 == proxy
     assert proxy2._pyroHandshake == "handshake"
     with Daemon(host="localhost",
                 port=12345,
                 nathost="localhost",
                 natport=9876) as daemon:
         ser = self.serializer.dumps(daemon)
         daemon2 = self.serializer.loads(ser)
         assert isinstance(daemon2, Daemon)
Exemplo n.º 10
0
 def run(self):
     daemon = Daemon()
     obj = MessagePrinter(self.gui)
     self.uri = daemon.register(obj, "pyrogui.message2")
     self.started.set()
     daemon.requestLoop()
Exemplo n.º 11
0
import time
from Pyro5.api import expose, Daemon

print("Autoreconnect using PYRO uri.")


@expose
class TestClass(object):
    def method(self, arg):
        print("Method called with %s" % arg)
        print("You can now try to stop this server with ctrl-C/ctrl-Break")
        time.sleep(1)


# We are responsible to (re)connect objects with the same object Id,
# so that the client can reuse its PYRO-uri directly to reconnect.
# There are a few options, such as depending on the Name server to
# maintain a name registration for our object (see the serverNS for this).
# Or we could store our objects in our own persistent database.
# But for this example we will just use a pre-generated id (fixed name).
# The other thing is that your Daemon must re-bind on the same port.
# By default Pyro will select a random port so we specify a fixed port.

with Daemon(port=7777) as daemon:
    uri = daemon.register(TestClass,
                          objectId="example.autoreconnect_fixed_objectid")
    print("Server started, uri: %s" % uri)
    daemon.requestLoop()
Exemplo n.º 12
0
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()
Exemplo n.º 13
0
                      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()
Exemplo n.º 14
0
from Pyro5.api import Daemon, serve
import excep


def my_error_handler(daemon, client_sock, method, vargs, kwargs, exception):
    print("\nERROR IN METHOD CALL USER CODE:")
    print(" client={} method={} exception={}".format(client_sock,
                                                     method.__qualname__,
                                                     repr(exception)))


daemon = Daemon()
daemon.methodcall_error_handler = my_error_handler

serve({excep.TestClass: "example.exceptions"},
      daemon=daemon,
      use_ns=True,
      verbose=True)
Exemplo n.º 15
0
#!/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()
Exemplo n.º 16
0
    @expose
    def factorize(self, n):
        print("factorize request received for", n)
        result = self._factorize(n)
        print("    -->", result)
        return result

    def _factorize(self, n):
        """simple algorithm to find the prime factorials of the given number n"""
        def isPrime(n):
            return not any(x for x in range(2, int(sqrt(n)) + 1) if n % x == 0)

        primes = []
        candidates = range(2, n + 1)
        candidate = 2
        while not primes and candidate in candidates:
            if n % candidate == 0 and isPrime(candidate):
                primes = primes + [candidate] + self._factorize(n // candidate)
            candidate += 1
        return primes


with Daemon(host=Pyro5.socketutil.get_ip_address(None)) as daemon:
    # create a unique name for this worker (otherwise it overwrites other workers in the name server)
    worker_name = "Worker_%d@%s" % (os.getpid(), socket.gethostname())
    print("Starting up worker", worker_name)
    uri = daemon.register(Worker)
    with locate_ns() as ns:
        ns.register(worker_name, uri, metadata={"example3.worker.factorizer"})
    daemon.requestLoop()
Exemplo n.º 17
0
 def run(self):
     with Daemon() as daemon:
         daemon.register(self.chatter)
         daemon.requestLoop(lambda: not self.chatter.abort)
Exemplo n.º 18
0
Arquivo: server.py Projeto: vtok/py_gl
import time
from Pyro5.api import expose, Daemon

print("Autoreconnect using PYRO uri.")


@expose
class TestClass(object):
    def method(self, arg):
        print("Method called with %s" % arg)
        print("You can now try to stop this server with ctrl-C/ctrl-Break")
        time.sleep(1)


# We are responsible to (re)connect objects with the same object Id,
# so that the client can reuse its PYRO-uri directly to reconnect.
# There are a few options, such as depending on the Name server to
# maintain a name registration for our object (see the serverNS for this).
# Or we could store our objects in our own persistent database.
# But for this example we will just use a pre-generated id (fixed name).
# The other thing is that your Daemon must re-bind on the same port.
# By default Pyro will select a random port so we specify a fixed port.

with Daemon(port=3002) as daemon:
    uri = daemon.register(TestClass,
                          objectId="example.autoreconnect_fixed_objectid")
    print("Server started, uri: %s" % uri)
    daemon.requestLoop()
Exemplo n.º 19
0
        z = complex(zr, zi)
        c = z
        for iters in range(self.maxiters + 1):
            if z.real * z.real + z.imag * z.imag > 4:  # abs(z) > 2
                break
            z = z * z + c
        if iters >= self.maxiters:
            return 0, 0, 0
        abs_z = math.sqrt(z.real * z.real + z.imag * z.imag)  # abs(z)
        r = (iters + 32) % 255
        g = (iters - math.log(abs_z)) % 255
        b = (abs_z * iters) % 255
        return int(r), int(g), int(b)


if __name__ == "__main__":
    with Daemon() as d:
        uri_1 = d.register(Mandelbrot)
        uri_2 = d.register(MandelbrotColorPixels)
        with locate_ns() as ns:
            ns.register(Mandelbrot._pyroId,
                        uri_1,
                        safe=True,
                        metadata={"class:mandelbrot_calc"})
            ns.register(MandelbrotColorPixels._pyroId,
                        uri_2,
                        safe=True,
                        metadata={"class:mandelbrot_calc_color"})
        print("Mandelbrot calculation server ready.")
        d.requestLoop()
Exemplo n.º 20
0
def start_maestral_daemon(config_name: str = "maestral",
                          log_to_stdout: bool = False,
                          start_sync: bool = False) -> None:
    """
    Starts the Maestral daemon with event loop in the current thread. Startup is race
    free: there will never be two daemons running for the same config.

    Wraps :class:`main.Maestral` as Pyro daemon object, creates a new instance and
    starts an asyncio event loop to listen for requests on a unix domain socket. This
    call will block until the event loop shuts down. When this function is called from
    the main thread on macOS, the asyncio event loop uses Cocoa's CFRunLoop to process
    event. This allows integration with Cocoa frameworks which use callbacks to process
    use input such as clicked notifications, etc, and potentially allows showing a GUI.

    :param config_name: The name of the Maestral configuration to use.
    :param log_to_stdout: If ``True``, write logs to stdout.
    :param start_sync: If ``True``, start syncing once the daemon has started.
    :raises: :class:`RuntimeError` if a daemon for the given ``config_name`` is already
        running.
    """

    import asyncio
    from maestral.main import Maestral

    if threading.current_thread() is not threading.main_thread():
        raise RuntimeError("Must run daemon in main thread")

    # acquire PID lock file
    lock = maestral_lock(config_name)

    if not lock.acquire():
        raise RuntimeError("Maestral daemon is already running")

    # Nice ourselves to give other processes priority. We will likely only
    # have significant CPU usage in case of many concurrent downloads.
    os.nice(10)

    # catch sigterm and shut down gracefully
    signal.signal(signal.SIGTERM, _sigterm_handler)

    # integrate with CFRunLoop in macOS, only works in main thread
    if sys.platform == "darwin":

        logger.debug("Cancelling all tasks from asyncio event loop")

        from rubicon.objc.eventloop import EventLoopPolicy  # type: ignore

        # clean up any pending tasks before we change the event loop policy
        # this is necessary if previous code has run an asyncio loop

        loop = asyncio.get_event_loop()
        try:
            # Python 3.7 and higher
            all_tasks = asyncio.all_tasks(loop)
        except AttributeError:
            # Python 3.6
            all_tasks = asyncio.Task.all_tasks(loop)
        pending_tasks = [t for t in all_tasks if not t.done()]

        for task in pending_tasks:
            task.cancel()

        loop.run_until_complete(
            asyncio.gather(*pending_tasks, return_exceptions=True))
        loop.close()

        logger.debug("Integrating with CFEventLoop")

        # set new event loop policy
        asyncio.set_event_loop_policy(EventLoopPolicy())

    # get the default event loop
    loop = asyncio.get_event_loop()

    sd_notifier = sdnotify.SystemdNotifier()

    # notify systemd that we have started
    if NOTIFY_SOCKET:
        logger.debug("Running as systemd notify service")
        logger.debug("NOTIFY_SOCKET = %s", NOTIFY_SOCKET)
        sd_notifier.notify("READY=1")

    # notify systemd periodically if alive
    if IS_WATCHDOG and WATCHDOG_USEC:

        async def periodic_watchdog() -> None:

            if WATCHDOG_USEC:

                sleep = int(WATCHDOG_USEC)
                while True:
                    sd_notifier.notify("WATCHDOG=1")
                    await asyncio.sleep(sleep / (2 * 10**6))

        logger.debug("Running as systemd watchdog service")
        logger.debug("WATCHDOG_USEC = %s", WATCHDOG_USEC)
        logger.debug("WATCHDOG_PID = %s", WATCHDOG_PID)
        loop.create_task(periodic_watchdog())

    # get socket for config name
    sockpath = sockpath_for_config(config_name)
    logger.debug(f"Socket path for '{config_name}' daemon: '{sockpath}'")

    # clean up old socket
    try:
        os.remove(sockpath)
    except FileNotFoundError:
        pass

    # expose maestral as Pyro server
    # convert management methods to one way calls so that they don't block

    logger.debug("Creating Pyro daemon")

    ExposedMaestral = expose(Maestral)

    ExposedMaestral.start_sync = oneway(ExposedMaestral.start_sync)
    ExposedMaestral.stop_sync = oneway(ExposedMaestral.stop_sync)
    ExposedMaestral.pause_sync = oneway(ExposedMaestral.pause_sync)
    ExposedMaestral.resume_sync = oneway(ExposedMaestral.resume_sync)
    ExposedMaestral.shutdown_daemon = oneway(ExposedMaestral.shutdown_daemon)

    maestral_daemon = ExposedMaestral(config_name, log_to_stdout=log_to_stdout)

    if start_sync:
        logger.debug("Starting sync")
        maestral_daemon.start_sync()

    try:

        logger.debug("Starting event loop")

        with Daemon(unixsocket=sockpath) as daemon:
            daemon.register(maestral_daemon, f"maestral.{config_name}")

            for socket in daemon.sockets:
                loop.add_reader(socket.fileno(), daemon.events, daemon.sockets)

            loop.run_until_complete(maestral_daemon.shutdown_complete)

            for socket in daemon.sockets:
                loop.remove_reader(socket.fileno())

    except Exception:
        traceback.print_exc()
    finally:

        if NOTIFY_SOCKET:
            # notify systemd that we are shutting down
            sd_notifier.notify("STOPPING=1")
Exemplo n.º 21
0
import os
from Pyro5.api import expose, Daemon


@expose
class Thingy(object):
    def message(self, arg):
        print("Message received:", arg)
        return "Roger!"


if os.path.exists("example_unix.sock"):
    os.remove("example_unix.sock")

with Daemon(unixsocket="example_unix.sock") as d:
    uri = d.register(Thingy, "example.unixsock")
    print("Server running, uri=", uri)
    d.requestLoop()
Exemplo n.º 22
0
def start_maestral_daemon(config_name: str = "maestral",
                          log_to_stderr: bool = False,
                          start_sync: bool = False) -> None:
    """
    Starts the Maestral daemon with event loop in the current thread.

    Startup is race free: there will never be more than one daemon running with the same
    config name. The daemon is a :class:`maestral.main.Maestral` instance which is
    exposed as Pyro daemon object and listens for requests on a unix domain socket. This
    call starts an asyncio event loop to process client requests and blocks until the
    event loop shuts down. On macOS, the event loop is integrated with Cocoa's
    CFRunLoop. This allows processing Cocoa events and callbacks, for instance for
    desktop notifications.

    :param config_name: The name of the Maestral configuration to use.
    :param log_to_stderr: If ``True``, write logs to stderr.
    :param start_sync: If ``True``, start syncing once the daemon has started. If the
        ``start_sync`` call fails, an error will be logged but not raised.
    :raises RuntimeError: if a daemon for the given ``config_name`` is already running.
    """

    import asyncio
    from .main import Maestral
    from .logging import scoped_logger, setup_logging

    setup_logging(config_name, log_to_stderr)
    dlogger = scoped_logger(__name__, config_name)

    dlogger.info("Starting daemon")

    if threading.current_thread() is not threading.main_thread():
        dlogger.error("Must run daemon in main thread")
        raise RuntimeError("Must run daemon in main thread")

    dlogger.debug("Environment:\n%s", pformat(os.environ.copy()))

    # acquire PID lock file
    lock = maestral_lock(config_name)

    if lock.acquire():
        dlogger.debug("Acquired daemon lock: %s", lock.path)
    else:
        dlogger.error("Could not acquire lock, daemon is already running")
        raise RuntimeError("Daemon is already running")

    # Nice ourselves to give other processes priority.
    os.nice(10)

    # Integrate with CFRunLoop in macOS.
    if IS_MACOS:

        dlogger.debug("Integrating with CFEventLoop")

        from rubicon.objc.eventloop import EventLoopPolicy  # type: ignore

        asyncio.set_event_loop_policy(EventLoopPolicy())

    # Get the default event loop.
    loop = asyncio.get_event_loop()

    sd_notifier = sdnotify.SystemdNotifier()

    # Notify systemd that we have started.
    if NOTIFY_SOCKET:
        dlogger.debug("Running as systemd notify service")
        dlogger.debug("NOTIFY_SOCKET = %s", NOTIFY_SOCKET)
        sd_notifier.notify("READY=1")

    # Notify systemd periodically if alive.
    if IS_WATCHDOG and WATCHDOG_USEC:

        async def periodic_watchdog() -> None:

            if WATCHDOG_USEC:

                sleep = int(WATCHDOG_USEC)
                while True:
                    sd_notifier.notify("WATCHDOG=1")
                    await asyncio.sleep(sleep / (2 * 10**6))

        dlogger.debug("Running as systemd watchdog service")
        dlogger.debug("WATCHDOG_USEC = %s", WATCHDOG_USEC)
        dlogger.debug("WATCHDOG_PID = %s", WATCHDOG_PID)
        loop.create_task(periodic_watchdog())

    # Get socket for config name.
    sockpath = sockpath_for_config(config_name)
    dlogger.debug(f"Socket path: '{sockpath}'")

    # Clean up old socket.
    try:
        os.remove(sockpath)
    except FileNotFoundError:
        pass

    # Expose maestral as Pyro server. Convert management
    # methods to one way calls so that they don't block.

    dlogger.debug("Creating Pyro daemon")

    ExposedMaestral = expose(Maestral)

    ExposedMaestral.start_sync = oneway(ExposedMaestral.start_sync)
    ExposedMaestral.stop_sync = oneway(ExposedMaestral.stop_sync)
    ExposedMaestral.shutdown_daemon = oneway(ExposedMaestral.shutdown_daemon)

    maestral_daemon = ExposedMaestral(config_name, log_to_stderr=log_to_stderr)

    if start_sync:
        dlogger.debug("Starting sync")
        maestral_daemon.start_sync()

    try:

        dlogger.debug("Starting event loop")

        with Daemon(unixsocket=sockpath) as daemon:
            daemon.register(maestral_daemon, f"maestral.{config_name}")

            # Reduce Pyro's housekeeping frequency from 2 sec to 20 sec.
            # This avoids constantly waking the CPU when we are idle.
            if daemon.transportServer.housekeeper:
                daemon.transportServer.housekeeper.waittime = 20

            for socket in daemon.sockets:
                loop.add_reader(socket.fileno(), daemon.events, daemon.sockets)

            # Handle sigterm gracefully.
            signals = (signal.SIGHUP, signal.SIGTERM, signal.SIGINT)
            for s in signals:
                loop.add_signal_handler(s, maestral_daemon.shutdown_daemon)

            loop.run_until_complete(maestral_daemon.shutdown_complete)

            for socket in daemon.sockets:
                loop.remove_reader(socket.fileno())

            # Prevent Pyro housekeeping from blocking shutdown.
            daemon.transportServer.housekeeper = None

    except Exception as exc:
        dlogger.error(exc.args[0], exc_info=True)
    finally:

        if NOTIFY_SOCKET:
            # Notify systemd that we are shutting down.
            sd_notifier.notify("STOPPING=1")
Exemplo n.º 23
0
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()
Exemplo n.º 24
0
from Pyro5.api import expose, Daemon, Proxy


# 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!")
Exemplo n.º 25
0
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()
# this only works on Linux
# it uses the abstract namespace socket feature.

from Pyro5.api import expose, Daemon


@expose
class Thingy(object):
    def message(self, arg):
        print("Message received:", arg)
        return "Roger!"


with Daemon(unixsocket="\0example_unix.sock"
            ) as d:  # notice the 0-byte at the start
    uri = d.register(Thingy, "example.unixsock")
    print("Server running, uri=", uri)
    string_uri = str(uri)
    print(
        "Actually, the uri contains a 0-byte, make sure you copy the part between the quotes to the client:"
    )
    print(repr(string_uri))
    d.requestLoop()
Exemplo n.º 27
0
Arquivo: server.py Projeto: gst/Pyro5
import os
from Pyro5.api import expose, Daemon


class QuoteGen(object):
    @expose
    def quote(self):
        try:
            quote = os.popen('fortune').read()
            if len(quote) > 0:
                return quote
            return "This system cannot provide you a good fortune, install 'fortune'"
        except:
            return "This system knows no witty quotes :-("


with Daemon() as daemon:
    quote1 = QuoteGen()
    quote2 = QuoteGen()

    uri1 = daemon.register(quote1)  # let Pyro create a unique name for this one
    uri2 = daemon.register(quote2, "example.quotegen")  # provide a logical name ourselves

    print("QuoteGen is ready, not using the Name Server.")
    print("You can use the following two URIs to connect to me:")
    print(uri1)
    print(uri2)

    daemon.requestLoop()
Exemplo n.º 28
0
        self._symbols = symbols

    def quotes(self):
        while True:
            symbol = random.choice(self.symbols)
            yield symbol, round(random.uniform(5, 150), 2)
            time.sleep(random.random() / 2.0)

    @property
    def name(self):
        return self._name

    @property
    def symbols(self):
        return self._symbols


if __name__ == "__main__":
    nasdaq = StockMarket("NASDAQ", ["AAPL", "CSCO", "MSFT", "GOOG"])
    newyork = StockMarket("NYSE", ["IBM", "HPQ", "BP"])
    # Add the proper "host" and "port" arguments for the construction
    # of the Daemon so it can be accessed remotely
    with Daemon(host=HOST_IP, port=HOST_PORT) as daemon:
        nasdaq_uri = daemon.register(nasdaq)
        newyork_uri = daemon.register(newyork)
        with locate_ns() as ns:
            ns.register("example.stockmarket.nasdaq", nasdaq_uri)
            ns.register("example.stockmarket.newyork", newyork_uri)
        print("Stockmarkets available.")
        daemon.requestLoop()
Exemplo n.º 29
0
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)
Exemplo n.º 30
0
# If we KNOW 100% that PYRONAME-uris are the only thing used to access our
# 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!