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.