import time
from io import BytesIO, BufferedReader
from pathlib import Path
from socketserver import UnixStreamServer,StreamRequestHandler
from fastcore.parallel import threaded
core
fastdaemon protocol and client
Since this module defines the client, it’s important that it has minimal dependencies for us to actually benefit from faster startup. The protocol is largely based on fastcgi
though much less feature-full.
Protocol
send_record
send_record (w, c)
Send a sequence of length-prefixed utf-8-encoded strings
= ['from fastcore.all import *', 'nbdev_clean --stdin']
ss = BytesIO()
f
send_record(f.write, ss)= f.getvalue(); b b
b'\x00\x00\x00\x1afrom fastcore.all import *\x00\x00\x00\x17nbdev_clean --stdin'
_recv_len(BufferedReader(BytesIO(b)).read)
26
recv_record
recv_record (r)
Receive two variable-length utf-8-encoded strings
recv_record(BytesIO(b).read)
['from fastcore.all import *', 'nbdev_clean --stdin']
start_client
start_client (port, host=None, dgram=False)
Create a socket
client on port
, with optional host
, of type dgram
transfer
transfer (data, port, host=None, dgram=False)
Send a request and receive a reply in one socket using the fastdaemon protocol
class EchoHandler(StreamRequestHandler):
def handle(self): self.wfile.write(self.rfile.readline())
= Path('fdaemon.sock')
p if p.exists(): p.unlink()
@threaded
def _f():
with UnixStreamServer(str(p), EchoHandler) as srv: srv.handle_request()
_f()0.2) # wait for server to start time.sleep(
'Input via stdin', 'world\n'], str(p)) # trailing \n is required since TestHandler uses `readline` transfer([
['Input via stdin', 'world\n']
Client
fastdaemon_client
fastdaemon_client (argv=None)
Forward sys.argv
and sys.stdin
to server and write response to sys.stdout
and sys.stderr
!fastdaemon_client -h
usage: fastdaemon_client [-h] [--host HOST] [--dgram] port
Forward `sys.argv` and `sys.stdin` to server and write response to
`sys.stdout` and `sys.stderr`
positional arguments:
port Server port. Use int for TCP, and str for Unix socket
optional arguments:
-h, --help show this help message and exit
--host HOST Server host (default: `socket.gethostname()`)
--dgram Use `SOCK_DGRAM`?