hunchentoot中的特殊变量

时间:2016-10-22 09:33:57

标签: common-lisp sbcl hunchentoot

目前,我正在为hunchentoot开发2个基于网络的工具 在开始hunchentoot之前,我想用let设置一些特殊变量,这样在hunchentoot运行时就会有值。

喜欢:

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

但是,一旦处理程序开具发票,它们就不会再接合,并且 db-path 会回落到其全局状态(这是零)。

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

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

Debian Jessie使用的环境是SBCL 1.2.4。

1 个答案:

答案 0 :(得分: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)))

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

  

一旦读取请求,就会调用此函数   已创建REQUEST对象。它的工作是实际处理   请求,即返回给客户的东西。

     

可能是一个好地方   适用于专门用于ACCEPTOR子类的方法   绑定或重新绑定特殊变量,然后您可以访问这些变量   处理程序。

我鼓励您阅读Hunchentoot's documentation

特殊变量和线程

您观察到的行为是因为:

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

      

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

         

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

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