Skip to content

Instantly share code, notes, and snippets.

@quark-zju
Last active May 12, 2016 23:05
Show Gist options
  • Save quark-zju/015c448b548bc6fbad4105868e2028ac to your computer and use it in GitHub Desktop.
Save quark-zju/015c448b548bc6fbad4105868e2028ac to your computer and use it in GitHub Desktop.
#! /usr/bin/env python3
# quick & dirty preforked echo server listening on /tmp/server
# client: socat unix-connect:/tmp/server stdout
import os, sys, time, socketserver
class PreforkMixIn:
max_nchildren = 3
children = None
def spawn_workers_forever(self, interval=0.5):
if self.children is None:
self.children = set()
while self.running():
self.create_workers()
self.reap_workers()
time.sleep(interval)
def running(self):
return not os.path.exists('/tmp/exit')
def create_worker(self):
pid = os.fork()
assert pid >= 0
if pid == 0:
try:
self.serve_forever()
except Exception as ex:
print(ex)
finally:
sys.exit(0)
else:
print('added worker: %s' % pid)
self.children.add(pid)
def create_workers(self, interval=0.5):
while len(self.children) < self.max_nchildren:
self.create_worker()
time.sleep(interval)
def reap_workers(self):
for pid in self.children.copy():
try:
pid, _ = os.waitpid(pid, os.WNOHANG)
if pid:
print('removed worker: %s' % pid)
self.children.discard(pid)
except ChildProcessError:
self.children.discard(pid)
except OSError:
pass
class myhandler(socketserver.StreamRequestHandler):
def handle(self):
print('serving from pid %s' % os.getpid())
while 1:
data = self.rfile.read(1)
if not data:
break
self.wfile.write(data)
class myserver(PreforkMixIn, socketserver.UnixStreamServer):
pass
if os.path.exists('/tmp/server'):
os.unlink('/tmp/server')
server = myserver('/tmp/server', myhandler)
server.spawn_workers_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment