On 2/14/2014 03:45, David Golden wrote:
On Thu, Feb 13, 2014 at 11:37 PM, Warren Young <warren@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.