Skip to content

Instantly share code, notes, and snippets.

@danielperna84
Created April 3, 2019 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielperna84/604dfb3cd3fd8021bff5209ad92cdff7 to your computer and use it in GitHub Desktop.
Save danielperna84/604dfb3cd3fd8021bff5209ad92cdff7 to your computer and use it in GitHub Desktop.
Python Unix Domain Socket SocketServer with ThreadingMixin and Multiprocessing
#!/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()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment