hunchentoot 中的特殊变量

Special variable in hunchentoot

目前,我正在使用 hunchentoot 开发 2 个基于 Web 的工具以满足我自己的需要。
在开始 hunchentoot 之前,我想用 let 设置一些特殊变量,以便在 hunchentoot 处于 运行ning.

时可以使用这些值

喜欢:

(let ((*db-path* "my-db-file"))
  (start-hunchentoot))

但是,一旦处理程序被开具发票,它们就不再处于 let 中并且 db-path 回落到其全局状态(即 nil)。

目前我正在通过在每个处理程序中编写 let 来解决这个问题。
但是,我想要一种更通用的方法,这样我就可以 运行 两个具有不同 db-path 的应用程序 运行-time.

是否可以通过某种方式设置 db-path,使其对一个 hunchentoot 实例有效,而不对另一个实例有效?

使用的环境是Debian Jessie上的SBCL 1.2.4

环绕法

db-path 添加为接受器中的插槽可能是一个合适的选择。但是,您也可以为 handle-request 编写一个 around 方法。假设 *my-acceptor* 是全局绑定的:

(defmethod hunchentoot:handle-request :around ((acceptor (eql *my-acceptor*)) request)
  (let ((*db-path* "my-db-file"))
    (call-next-method)))

当然,您不需要专门研究EQL,您可以定义自己的subclass。 around 方法相对于在 class 实例中存储配置变量的优势在于您保留了使用特殊变量的好处,即绑定在动态范围内的任何地方都是可见的。 这是 Lispdoc 上可见的文档字符串关于 handle-request(强调我的)的内容:

This function is called once the request has been read and a REQUEST object has been created. Its job is to actually handle the request, i.e. to return something to the client.

Might be a good place for around methods specialized for your subclass of ACCEPTOR which bind or rebind special variables which can then be accessed by your handlers.

我鼓励你阅读 Hunchentoot's documentation

特殊变量和线程

您观察到的行为是因为:

  • 服务器 运行 在另一个线程中。
  • 如解释的那样,动态绑定对每个线程都是本地的 in the manual:

    The interaction of special variables with multiple threads is mostly as one would expect, with behaviour very similar to other implementations.

    • global special values are visible across all threads;
    • bindings (e.g. using LET) are local to the thread;
    • threads do not inherit dynamic bindings from the parent thread

如果您创建自己的线程,则可以构建一个闭包来根据需要绑定变量。您还可以依赖可移植的 bordeaux-threads 库,该库采用在线程内有效的绑定列表。