Hunchentoot special variable

I am currently developing 2 web tools for my own needs using hunchentoot.
Before starting hunchentoot, I want to set some special variable to allow the values โ€‹โ€‹to be available while hunchentoot is running.

Like:

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

But, as soon as the handlers receive the invoices, they will not be seams to be in an empty place, and the db-path returns to its global state (which is zero).

At the moment, I resolve this by writing let in each handler.
But I want a more general approach so that I can run both applications with different db paths in a single time interval.

Is it possible to set the db path so that it is valid for one hunchentoot instance and not another?

The environment used is SBCL 1.2.4 on Debian Jessie.

+6
source share
1 answer

Method around

Adding db-path as a slot in the acceptor may be an appropriate option. However, you can also write an around method for handle-request . Assuming *my-acceptor* globally bound:

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

Of course, you donโ€™t need to specialize in EQL , instead you can define your own subclass. The advantage of the around method associated with storing the configuration variable in an instance of the class is that you retain the benefits of using special variables, i.e. Bindings are visible throughout the dynamic area. This is what the documentation line visible on Lispdoc says about handle-request (my highlight):

This function is called after the request has been read and the REQUEST object has been created. His task is to actually cope with the request, i.e. return something to the customer.

Perhaps a good place for methods specifically designed for your ACCEPTOR subclass, which bind or rearrange special variables that your handlers can then access.

I recommend that you read the Hunchentoot documentation .

Special Variables and Streams

The behavior you observe is related to the fact that:

  • The server is running in a different thread.
  • Dynamic bindings are local to each thread, as described in the manual :

    The interaction of special variables with multiple threads is basically, as you would expect, with behavior very similar to other implementations.

    • Global special values โ€‹โ€‹are visible for all threads.
    • bindings (e.g. using LETs) are local to the flow;
    • threads do not inherit dynamic bindings from the parent thread

If you create your own threads, you can create a closure that binds the variables as you wish. You can also rely on the portable bordeaux-threads library, which takes a list of bindings to be efficient inside the thread.

+7
source

Source: https://habr.com/ru/post/1011582/


All Articles