-
-
Save ibeex/6917820 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import signal | |
import sys | |
import errno | |
from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCServer | |
# BOOK-KEEPING | |
_PIDS = [] | |
def _kronos(signum, frame): | |
'''As Kronos did before us, we too may have to devour our children''' | |
for pid in _PIDS: | |
try: | |
os.kill(pid, signum) | |
except OSError, e: | |
if e.errno == errno.ESRCH: | |
_PIDS.remove(pid) | |
# wait on all child processes | |
while len(_PIDS): | |
pid, rc = os.waitpid(-1, 0) | |
_PIDS.remove(pid) | |
# exit non-zero to signal abnormal termination | |
sys.exit(1) | |
def _gogentle(signum, frame): | |
'''Do not throw a KeyboardInterrupt Error''' | |
os._exit(1) | |
# API | |
def add(x, y): | |
'''Add x and y''' | |
return x + y | |
def subtract(x, y): | |
'''Subtract y from x''' | |
return x - y | |
# server | |
def main(name, *argv): | |
global _PIDS | |
# JSON-RPC over HTTP on INET socket localhost:8888 | |
# under the hood, this calls `socket.bind` then `socket.listen` | |
s = SimpleJSONRPCServer(( argv[0], int(argv[1]), )) | |
# register our logging math functions | |
for fn in ( add, subtract, ): | |
s.register_function(fn) | |
# simple pre-fork server, fork before accept | |
for i in range(int(argv[2])): | |
# fork our current process | |
pid = os.fork() | |
# if we are the child fork ... | |
if 0 == pid: | |
# die without unhandled exception | |
for signum in ( signal.SIGINT, signal.SIGTERM, ): | |
signal.signal(signum, _gogentle) | |
# under the hood, this calls `socket.accept` | |
s.serve_forever() | |
os._exit(0) | |
# if we are the papa fork | |
else: | |
_PIDS.append(pid) | |
# setup signal relaying for INT and TERM | |
for signum in ( signal.SIGINT, signal.SIGTERM, ): | |
signal.signal(signum, _kronos) | |
# wait on the kids | |
while len(_PIDS): | |
pid, rc = os.waitpid(-1, 0) | |
_PIDS.remove(pid) | |
return 0 | |
if __name__ == '__main__': | |
sys.exit(main(*sys.argv)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment