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 库,该库采用在线程内有效的绑定列表。
目前,我正在使用 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 库,该库采用在线程内有效的绑定列表。