[dancer-users] Lock session files with Dancer2::Session::YAML?

Maxwell Carey mcarey at ucar.edu
Mon May 5 23:10:30 BST 2014


On 05/03/2014 12:29 AM, Stefan Hornburg (Racke) wrote:
> On 05/02/2014 10:07 PM, Maxwell Carey wrote:
>> Is it possible to lock session files created by Dancer2::Session::YAML in order to avoid race conditions when two processes try to write to the same session at the same time? For example, if I have the following routes:
>>
>> get '/foo' => sub {
>>      my $foo = session 'foo';
>>      session 'foo' => ++$foo;
>> };
>>
>> get '/bar' => sub {
>>      my $bar = session 'bar';
>>      session 'bar' => ++$bar;
>> };
>>
>> and both are called at the same time, one route "wins", resulting in either the value of 'foo' or 'bar' being updated, but not both.
>>
>> If it's not possible (or easy) to lock the file, I would be open to an alternative storage backend, although I was hoping to keep things as simple as possible, i.e.
>> I don't want to have to spin up a new MySQL database or equivalent. The existing Dancer2::Session:: backends all seem somewhat...involved. Any ideas?
>>
> It makes a lot of sense to lock sessions, in any session backend (not only file based). Locking file based sessions
> isn't a big deal.

As it turns out, Dancer2::Core::Role::SessionFactory::File already uses 
flock, with a shared lock for reads and an exclusive lock for writes. 
The problem with my code is that the entire update operation needs to 
occur inside a single lock, i.e. I need to lock the file before reading 
the value and unlock it after writing the value. It seems like there's 
no way to do this directly without mucking around in the internals. A 
better approach might be to use a semaphore.


More information about the dancer-users mailing list