lisp-network-server
-------------------

A simple framework for writing network services in Common Lisp. 

Basic idea: 
  LNS provides - much like inetd - the core infrastructure to listen
  on the network, accept connections, hand over these connections to
  specialised handlers and close these connections in case of
  (unhandled) errors. The specialised handlers in our case are Lisp
  functions running in a multithreaded environment, with one thread per
  session (with session being defined as: a connection that is
  accepted and currently processed). 

  So LNS gives you the basic framework and all the implementor of a
  network service has to do is:
   - write code that gets handed a two-way stream and does
     stuff with it, terminates when done
   - register his handler with a port number with LNS

  Keep in mind that you hand over function objects to LNS. So if you
  load & compile a new definition of the function you handed LNS to
  handle a request, nothing will change ... because the old function
  object is _still_ there. You need to unregister the old handler 
  function and register the new one for your changes to have an effect.


Design:
 - register-service-handler registers a service handler for
   a port and starts the network listener for that port
 - the listener threads does a listen(2)
 - upon return of listen(2), the listening thread first checks the 
   current load (defined as number of threads running) against the
   load-limit (maximum number of threads) and if it is low enough
   accept(2)s the connection, and starts a handler with this connected socket
 - the listener threads goes back to listen for incoming connections
 - the handler thread handles the connection and exits when done,
   closing the connection
 - the load check checks the current number of threads against
   the configured maximum and does a sleep(1) while the current number
   of threads is higher than the configured limit, the number of
   maximum threads can be set/queried by external packages and it
   includes all active threads in the image
 - to minimize the usual problems of multi-threaded designs, I aim
   to only share read-only data

Interface:
 - the service-handlers need to be functions with five arguments:
   - stream - the network link as two-way-stream
   - ip - IP address the socket is bound to
   - port - port the socket is bound to
   - peer-ip - IP address of peer, as string
   - peer-port - originating port on the peer, integer
 - see simple-tcp.lisp for examples

Implementation:
 - threads names are used for identification of threads
   - threads are selectively killed if necessary to activate 
     configuration updates, so pay close attention to their names
   - network listeners are named: "network listener port/protocol",
     so a smtp listener might be "network listener 25/tcp"
