Question

I cannot figure out a way to use package variables (or anything of the sort) in Dancer apps when run with Starman. I suppose it is somehow related to Starman's preforking but that is supposed to be a feature, not a bug.

Here's the example Dancer app:

package nafig;
use Dancer;

my $a = 0;
$b = 0;
$nafig::c = 0;

any '/' => sub {
    warn join " ", $a++, $b++, $nafig::c++;
};

start;

Then I make 3 consecutive calls to that app. First, I run it with plack reference server, and everything works as expected:

$ plackup app.pl
HTTP::Server::PSGI: Accepting connections at http://0:5000/
0 0 0 at ... blah-blah-blah
1 1 1 at ... blah-blah-blah
2 2 2 at ... blah-blah-blah

But when I do the same thing with Starman, I get the following.

$ plackup -s Starman app.pl
2013/11/17-23:33:35 Starman::Server (type Net::Server::PreFork) starting! pid(527)
Resolved [*]:5000 to [::]:5000, IPv6
Not including resolved host [0.0.0.0] IPv4 because it will be handled by [::] IPv6
Binding to TCP port 5000 on host :: with IPv6
Setting gid to "1000 1000 20 24 25 29 30 44 46 108 109 115 121 1000"
Starman: Accepting connections at http://*:5000/
0 0 0 at ... blah-blah-blah
0 0 0 at ... blah-blah-blah
0 0 0 at ... blah-blah-blah

However, when refreshing the page quickly, sometimes the values are incremented as expected. I guess, Starman remains in the same fork in those cases.

I'm surprised this question was never asked on stackoverflow before. Persistent variables seem useful to me, how do people dance without them?

Thanks in advance for any help.

Was it helpful?

Solution

You will need a module like Cache::Memcached which allows you to store state over forked threads.

something like this (untested)

use strict;
use warnings;

package nafig; #this should start with a capital letter
use Dancer;
use Cache::Memcached;

my $cache =  new Cache::Memcached {
    'servers' => ['127.0.0.1:11211'],
    'compress_threshold' => 10_000,
};

$cache->set("var1", 0);

any '/' => sub {

    my $value = $cache->get("var1");

    warn join " ", $value++;

    $cache->set("var1", $value);
};

start;

adapted from here http://perl.postbit.com/how-to-use-memcached-with-perl.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top