Shadowing special variables in threaded handlers
Duncan Bayne
duncan at bayne.id.au
Fri Dec 31 04:48:55 UTC 2021
Chun Tian writes:
> The difference here is that now (lambda (stream) ...) is a closure
> which will contain a local version of *foo* at the time when
> (create-server) is called. This kind of uses of lambda functions is
> like a cheap object with a member variable.
Thanks for the suggestion - yes, this does work as expected, but
introduces a difficulty with the API of the library.
The germinal code is as follows (edited to remove large swathes and just
focus on the relevant bits):
=====
(defvar *germinal-cert* "/etc/germinal/cert.pem")
(defvar *germinal-cert-key* "/etc/germinal/key.pem")
(defvar *germinal-tls-context* nil "Variable used to store global TLS context")
;; snip
(with-global-context (*germinal-tls-context* :auto-free-p (not background))
(usocket:socket-server host port #'gemini-handler ()
:multi-threading t
:element-type '(unsigned-byte 8)
:in-new-thread background)))
;; snip
(defun gemini-handler (stream)
"The main Gemini request handler. Sets up TLS and sets up request and response"
(handler-case
(let* ((tls-stream (make-ssl-server-stream stream
:certificate *germinal-cert*
:key *germinal-cert-key*))
;; snip
=====
So replacing the handler function with a lambda that creates a closure
works ... but breaks the non-testing case where you just want to setq
the special variables in your app startup and be done with it.
The best approach I can think of is something like ...
=====
;; snip
(with-global-context (*germinal-tls-context* :auto-free-p (not background))
(usocket:socket-server host port
(let ((*threaded-cert* *germinal-cert*)
(*threaded-cert-key* *germinal-cert-key*))
(lambda (stream) (gemini-handler stream)))
;; snip
(let* ((tls-stream (make-ssl-server-stream stream
:certificate *threaded-cert*
:key *threaded-cert-key*))
;; snip
=====
Which seems weird, but also gives the best of both worlds; the ability
to shadow variables for testing purposes, but also setq the *same*
variables for global configuration.
Thoughts / opinions?
--
Duncan Bayne
+61 420 817 082 | https://duncan.bayne.id.au/
I usually check my mail every 24 - 48 hours. If there's something
urgent going on, please send me an SMS or call me.
More information about the usocket-devel
mailing list