File size: 2,906 Bytes
43203b4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | (in-package :cl-user)
(defpackage clack.handler
(:use :cl)
(:import-from :clack.util
:find-handler)
(:import-from :bordeaux-threads
:threadp
:make-thread
:thread-alive-p
:destroy-thread)
(:import-from :usocket)
(:export :run
:stop))
(in-package :clack.handler)
(defstruct handler
server
swank-port
acceptor)
(defun run (app server &rest args
&key (address nil address-specified-p) use-thread
(swank-interface "127.0.0.1") swank-port debug
silent
&allow-other-keys)
(declare (ignorable swank-interface))
(let ((handler-package (find-handler server))
(bt2:*default-special-bindings* `((*standard-output* . ,*standard-output*)
(*error-output* . ,*error-output*)
,@bt2:*default-special-bindings*)))
(when (and debug
(not silent))
(format t "NOTICE: Running in debug mode. Debugger will be invoked on errors.
Specify ':debug nil' to turn it off on remote environments."))
(flet ((run-server ()
(when swank-port
#+swank
(swank:create-server :interface swank-interface :port swank-port :dont-close t)
#-swank
(error "Swank is required to use :swank-port but is not loaded. Load SLIME or Swank first."))
(apply (intern #.(string '#:run) handler-package)
app
:allow-other-keys t
(append
(and address-specified-p
(list :address
(usocket:host-to-hostname
(usocket:get-host-by-name address))))
args))))
(make-handler
:server server
:swank-port swank-port
:acceptor (if use-thread
(bt2:make-thread #'run-server
:name (format nil "clack-handler-~(~A~)" server)
:initial-bindings
`((bt2:*default-special-bindings* . ',bt2:*default-special-bindings*)
,@bt2:*default-special-bindings*))
(run-server))))))
(defun stop (handler)
(let ((acceptor (handler-acceptor handler))
(swank-port (handler-swank-port handler)))
(if (bt2:threadp acceptor)
(progn
(when (bt2:thread-alive-p acceptor)
(bt2:destroy-thread acceptor))
(sleep 0.5))
(let ((package (find-handler (handler-server handler))))
(funcall (intern #.(string '#:stop) package) acceptor)))
(when swank-port
#+swank
(swank:stop-server swank-port))
t))
|