[dancer-users] session() auto-flush

Warren Young warren at etr-usa.com
Fri Feb 14 18:41:44 GMT 2014


On 2/14/2014 03:45, David Golden wrote:
> On Thu, Feb 13, 2014 at 11:37 PM, Warren Young <warren at etr-usa.com> wrote:
>> I finally tracked it down to the fact that session(X, Y) automatically calls
>> flush() on the object for you, whereas session() with no parameters returns
>> a hashref that doesn't auto-flush itself.
>
> Really, session() with no parameters returns a session *object*, it
> happens to be implemented as a hash ref.  There's no magic to it.  To
> make objects do things, you have to call methods on them.

...But there *could* be magic to it.  :)

I tracked the problem down further.  It is that when you call 
Dancer::Session::YAML::retrieve() indirectly via Dancer::session(), it 
is loading the session object back up from disk, obliterating the 
contents of the previous object.

You can see the problem easily:

1. Create a new Dancer 1 project

2. Edit the lone route handler:

     session a => 1;
     session()->{b} = 2;
     session c => 3;

The 'b' line simulates my passing of session()'s return to another module.

3. Add session: "YAML" to config.yml

4. Run the app, hit the page, examine the session file:

--- !!perl/hash:Dancer::Session::YAML
a: 1
c: 3
id: 375432505278121443472247271047126129


My notion was that session() was returning the same global object, in 
the same way that request() does.  The 'b' field would remain in memory 
only until the 'c' field is written, which implicitly calls flush() due 
to the difference in the way session() handles parameters.

It would be even nicer if, at the end of a route handler's processing, 
Dancer would detect that there is a dirty session object and flush it 
for you.

"Exit without saving" is never a desired use case with session objects, 
as it can be for, say, word processing documents.

This doesn't happen with Dancer::Session::Simple for fairly obvious 
reasons.  However, I suspect it would happen with any other persistent 
session mechanism.

The "magic" I hinted at above would be to keep the session object loaded 
and in RAM from the first session() call until the end of the route 
handler, never reloading from disk, but auto-flushing at the end.

This would have the nice side benefit of speeding up session I/O. 
Really, there's not a lot of point of persisting the session object more 
than once per route call, is there?  There's even less point to 
repeatedly re-loading it from disk.  It's not like there's another 
process also writing to the same session.

...Or is there?  With a forking front end, do all calls from a 
particular client go to a particular Dancer app instance, or is that 
parallelized, too?

> I assume you're talking Dancer 1, here, right?

Yes, and I realize it's feature-frozen.  This behavior strikes me as 
bug-like, so I don't see that the freeze is a reason not to improve the 
behavior.


More information about the dancer-users mailing list