hunchentoot中的特殊变量

Fir*_*ain 6 sbcl common-lisp hunchentoot

目前,我正在使用hunchentoot为我自己的需求开发2个基于Web的工具.
在启动hunchentoot之前,我想设置一些特殊变量,因此在hunchentoot运行时可以使用值.

喜欢 :

(let ((*db-path* "my-db-file"))
  (start-hunchentoot))
Run Code Online (Sandbox Code Playgroud)

但是,一旦处理程序开具发票,它们就不再接合,而db-path又回落到其全局状态(为零).

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

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

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

cor*_*ump 7

围绕方法

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

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

当然,您不需要专门研究EQL,您可以改为定义自己的子类.around方法相对于在类实例中存储配置变量的优点是,您可以保留使用特殊变量的好处,即在动态范围内的任何位置都可以看到绑定.以下是文档字符串,可见Lispdoc说,对handle-request(重点煤矿):

一旦读取请求并创建了REQUEST对象,就会调用此函数.它的工作是实际处理请求,即将内容返回给客户端.

可能是围绕ACCEPTOR子类的专用方法的好地方,它们绑定或重新绑定特殊变量,然后由处理程序访问.

我鼓励您阅读Hunchentoot的文档.

特殊变量和线程

你观察到的行为是因为:

  • 服务器正在另一个线程中运行.
  • 动态绑定是每个线程的本地绑定,如手册中所述:

    特殊变量与多个线程的交互大多是人们所期望的,其行为与其他实现非常相似.

    • 所有线程都可以看到全局特殊值;
    • 绑定(例如,使用LET)是线程的本地;
    • 线程不从父线程继承动态绑定

如果你创建自己的线程,你可以构建一个闭包,根据需要绑定变量.您还可以依赖便携式bordeaux-threads库,它可以使一个绑定列表在一个线程内有效.