Lock session files with Dancer2::Session::YAML?
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?
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. Regards Racke -- LinuXia Systems => http://www.linuxia.de/ Expert Interchange Consulting and System Administration ICDEVGROUP => http://www.icdevgroup.org/ Interchange Development Team
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.
By the way, It is not safe to use YAML sessions with production site. I used YAML sessions in Dancer1 app and pretty soon there appeared tons of files with sessions and evrything broke, because there was no free inodes. On Tue, May 6, 2014 at 2:10 AM, Maxwell Carey <mcarey@ucar.edu> wrote:
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.
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
On 05/07/2014 02:43 PM, ???? ?????????? wrote:
By the way, It is not safe to use YAML sessions with production site. I used YAML sessions in Dancer1 app and pretty soon there appeared tons of files with sessions and evrything broke, because there was no free inodes.
The documentation for Dancer2::Session::YAML <https://metacpan.org/pod/Dancer2::Session::YAML#DESCRIPTION>, at least, says otherwise: This backend an [sic] perfectly be used in production environments, but two things should be kept in mind: The content of the session files is in plain text, and the session files should be purged by a CRON job. I haven't had any problems like you describe, so perhaps your issue was limited to Dancer::Session::YAML, which according to the docs <https://metacpan.org/pod/Dancer::Session::YAML#DESCRIPTION> is "not recommended...in production environments." Either that, or you just have too many visitors to your site ;)
Yes, I had problems with Dancer1 yaml sessions. And there were not so many visitors =) On Thu, May 8, 2014 at 1:05 AM, Maxwell Carey <mcarey@ucar.edu> wrote:
On 05/07/2014 02:43 PM, Иван Бессарабов wrote:
By the way, It is not safe to use YAML sessions with production site. I used YAML sessions in Dancer1 app and pretty soon there appeared tons of files with sessions and evrything broke, because there was no free inodes.
The documentation for Dancer2::Session::YAML, at least, says otherwise:
This backend an [sic] perfectly be used in production environments, but two things should be kept in mind: The content of the session files is in plain text, and the session files should be purged by a CRON job.
I haven't had any problems like you describe, so perhaps your issue was limited to Dancer::Session::YAML, which according to the docs is "not recommended...in production environments." Either that, or you just have too many visitors to your site ;)
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
participants (3)
-
Maxwell Carey -
Stefan Hornburg (Racke) -
Иван Бессарабов