Skip to content

Instantly share code, notes, and snippets.

@danielperna84
Created April 3, 2019 16:10
Show Gist options
  • Save danielperna84/604dfb3cd3fd8021bff5209ad92cdff7 to your computer and use it in GitHub Desktop.
Save danielperna84/604dfb3cd3fd8021bff5209ad92cdff7 to your computer and use it in GitHub Desktop.

Revisions

  1. danielperna84 created this gist Apr 3, 2019.
    80 changes: 80 additions & 0 deletions uds_socketserver.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,80 @@
    #!/usr/bin/python
    import os
    import sys
    import time
    import signal
    import logging
    import multiprocessing
    from multiprocessing import Process
    import SocketServer

    SERVER = None
    LOGLEVEL_MAPPING = {
    "critical": logging.CRITICAL,
    "error": logging.ERROR,
    "warning": logging.WARNING,
    "info": logging.INFO,
    "debug": logging.DEBUG
    }
    DEFAULT_LOGLEVEL = "debug"
    LOGLEVEL = LOGLEVEL_MAPPING.get(os.environ.get("LOGLEVEL", DEFAULT_LOGLEVEL))
    LOG = logging.getLogger(__name__)
    LOG.setLevel(LOGLEVEL)
    SO = logging.StreamHandler(sys.stdout)
    SO.setLevel(LOGLEVEL)
    SO.setFormatter(
    logging.Formatter('%(levelname)s:%(asctime)s:%(name)s:%(message)s'))
    LOG.addHandler(SO)
    SERVER_ADDRESS = './uds.sock'

    try:
    os.unlink(SERVER_ADDRESS)
    except OSError:
    if os.path.exists(SERVER_ADDRESS):
    raise

    def signal_handler(sig, frame):
    """Handle signal to shut down server."""
    global SERVER
    LOG.warning("Got signal: %s. Shutting down server." % str(sig))
    SERVER.server_close()
    for child in multiprocessing.active_children():
    LOG.warning("Terminating: %s" % child)
    child.terminate()
    sys.exit(0)

    def sleeper(duration):
    """Dummy process that would block a single-threaded server."""
    LOG.debug("sleeping for %s seconds" % duration)
    time.sleep(int(duration))
    LOG.debug("done sleeping")

    class ThreadingUDSServer(SocketServer.ThreadingMixIn, SocketServer.UnixStreamServer):
    pass

    class SockHandler(SocketServer.BaseRequestHandler):
    """
    The request handler class for our server.
    """
    def handle(self):
    self.data = self.request.recv(1024).strip()
    LOG.debug(self.data)
    if "status" in self.data.split(':'):
    self.request.sendall("processes:%s" % len(multiprocessing.active_children()))
    elif "sleep" in self.data.split(':'):
    _, duration = self.data.split(':')
    p = Process(target=sleeper, args=(duration,))
    p.start()
    self.request.sendall("started:%s" % p.name)
    else:
    self.request.sendall("unknown-command")

    def main():
    global SERVER
    signal.signal(signal.SIGINT, signal_handler)
    SERVER = ThreadingUDSServer(SERVER_ADDRESS, SockHandler)
    LOG.info("Created socket at %s" % SERVER_ADDRESS)
    SERVER.serve_forever()

    if __name__ == "__main__":
    main()