Dancer and forking
Dear all, Is there anything that I should be aware of if using fork() in a dancer application? I have some cache update code which can take a while to run, so I'd rather do it in the background. I've therefore done something like this: post '/data' => sub { my $template = ...; fork and return $template; update_cache; exit; } The actual code is in a module, but you get the idea. Thanks, Andy
Hi Andy, I tried to use threads and it did not worked for me (maybe because of non safe thread modules I am using) so I use fork in a production application and it works good. I have some issues some times with MySQL that I have not fixed yet but they do not happen very often. This is an example of how I use it: sub execute { # These 2 lines below were to eliminate the error that I mentioned before. It did not eliminated them just reduce them my $dbh = database(); $dbh->{InactiveDestroy} = 1; my $pid = fork(); if ($pid) { # This is the parent (Dancer) in case you want to do something here debug “Process started with PID $pid\n”; } elsif ($pid == 0) { # This is the child, here is where I do all I need $template = ... } else { debug “Could not fork: $!\n”; } # I have a variable to know if I’m running this sub from the web or from CLI if ($cli) { my $output = waitpid($pid, 0); print “The process finish with output: $output”; } return $template; } This is just an example, not the entire code. If someone has a suggestion or improvement, it is welcome. Thanks, Johandry
On Jul 7, 2015, at 2:58 PM, Andrew Beverley <andy@andybev.com> wrote:
Dear all,
Is there anything that I should be aware of if using fork() in a dancer application?
I have some cache update code which can take a while to run, so I'd rather do it in the background. I've therefore done something like this:
post '/data' => sub { my $template = ...; fork and return $template; update_cache; exit; }
The actual code is in a module, but you get the idea.
Thanks,
Andy
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
On 2015-07-08 00:58, Johandry Amador Segui wrote:
Hi Andy,
I tried to use threads and it did not worked for me (maybe because of non safe thread modules I am using) so I use fork in a production application and it works good. I have some issues some times with MySQL that I have not fixed yet but they do not happen very often.
This is an example of how I use it:
sub execute {
# These 2 lines below were to eliminate the error that I mentioned before. It did not eliminated them just reduce them my $dbh = database(); $dbh->{InactiveDestroy} = 1;
my $pid = fork();
if ($pid) { # This is the parent (Dancer) in case you want to do something here debug “Process started with PID $pid\n”;
} elsif ($pid == 0) { # This is the child, here is where I do all I need $template = ... } else { debug “Could not fork: $!\n”; }
# I have a variable to know if I’m running this sub from the web or from CLI if ($cli) { my $output = waitpid($pid, 0); print “The process finish with output: $output”; }
return $template; }
This is just an example, not the entire code. If someone has a suggestion or improvement, it is welcome.
Surely you need an exit() in there somewhere for the child process, otherwise you'll end up with lots of web server threads? Andy
Any chance one of you would like to write a short article about it for the Advent Calendar of 2016? :) On Wed, Jul 8, 2015 at 8:15 AM, Andrew Beverley <andy@andybev.com> wrote:
On 2015-07-08 00:58, Johandry Amador Segui wrote:
Hi Andy,
I tried to use threads and it did not worked for me (maybe because of non safe thread modules I am using) so I use fork in a production application and it works good. I have some issues some times with MySQL that I have not fixed yet but they do not happen very often.
This is an example of how I use it:
sub execute {
# These 2 lines below were to eliminate the error that I mentioned before. It did not eliminated them just reduce them my $dbh = database(); $dbh->{InactiveDestroy} = 1;
my $pid = fork();
if ($pid) { # This is the parent (Dancer) in case you want to do something here debug “Process started with PID $pid\n”;
} elsif ($pid == 0) { # This is the child, here is where I do all I need $template = ... } else { debug “Could not fork: $!\n”; }
# I have a variable to know if I’m running this sub from the web or from CLI if ($cli) { my $output = waitpid($pid, 0); print “The process finish with output: $output”; }
return $template; }
This is just an example, not the entire code. If someone has a suggestion or improvement, it is welcome.
Surely you need an exit() in there somewhere for the child process, otherwise you'll end up with lots of web server threads?
Andy
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
On Wed, 2015-07-08 at 14:56 +0200, Sawyer X wrote:
Any chance one of you would like to write a short article about it for the Advent Calendar of 2016? :)
Of course, no problem at all. I was actually concerned that what I was doing might be wrong/bad in some way, hence the post, but if it's fine and worth sharing then very happy! I'd also be happy to write something up about logging (regarding Plugin::LogReport which I'll post about here once some changes have been made), and the Plugin::Auth::Extensible changes that allow password resets etc. Andy
That would be great! On Wed, Jul 8, 2015 at 3:49 PM, Andrew Beverley <andy@andybev.com> wrote:
On Wed, 2015-07-08 at 14:56 +0200, Sawyer X wrote:
Any chance one of you would like to write a short article about it for the Advent Calendar of 2016? :)
Of course, no problem at all. I was actually concerned that what I was doing might be wrong/bad in some way, hence the post, but if it's fine and worth sharing then very happy!
I'd also be happy to write something up about logging (regarding Plugin::LogReport which I'll post about here once some changes have been made), and the Plugin::Auth::Extensible changes that allow password resets etc.
Andy
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
Exactly, I have it. I highlighted in red the exit from the child. Also (maybe is useful) I have a print with an ‘if $cli’ to print messages in the console (debugging or logging) when the sub is executed from the CLI. use POSIX qw(_exit); sub execute { # These 2 lines below were to eliminate the error that I mentioned before. It did not eliminated them just reduce them my $dbh = database(); $dbh->{InactiveDestroy} = 1; my $pid = fork(); if ($pid) { # This is the parent (Dancer) in case you want to do something here debug “Process started with PID $pid\n”; } elsif ($pid == 0) { # This is the child, here is where I do all I need $template = … $exit_code= … print “Something in the console” if $cli _exit($exit_code); } else { debug “Could not fork: $!\n”; } # I have a variable to know if I’m running this sub from the web or from CLI if ($cli) { my $output = waitpid($pid, 0); print “The process finish with output: $output”; } return $template; }
On Jul 7, 2015, at 11:15 PM, Andrew Beverley <andy@andybev.com> wrote:
On 2015-07-08 00:58, Johandry Amador Segui wrote:
Hi Andy, I tried to use threads and it did not worked for me (maybe because of non safe thread modules I am using) so I use fork in a production application and it works good. I have some issues some times with MySQL that I have not fixed yet but they do not happen very often. This is an example of how I use it: sub execute { # These 2 lines below were to eliminate the error that I mentioned before. It did not eliminated them just reduce them my $dbh = database(); $dbh->{InactiveDestroy} = 1; my $pid = fork(); if ($pid) { # This is the parent (Dancer) in case you want to do something here debug “Process started with PID $pid\n”; } elsif ($pid == 0) { # This is the child, here is where I do all I need $template = ... } else { debug “Could not fork: $!\n”; } # I have a variable to know if I’m running this sub from the web or from CLI if ($cli) { my $output = waitpid($pid, 0); print “The process finish with output: $output”; } return $template; } This is just an example, not the entire code. If someone has a suggestion or improvement, it is welcome.
Surely you need an exit() in there somewhere for the child process, otherwise you'll end up with lots of web server threads?
Andy
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
If it's CLI, can't you just set up the Console logger? You wouldn't need the if() there, only at a setup() method. On Wed, Jul 8, 2015 at 10:59 PM, Johandry Amador Segui <johandry@gmail.com> wrote:
Exactly, I have it. I highlighted in red the exit from the child.
Also (maybe is useful) I have a print with an ‘if $cli’ to print messages in the console (debugging or logging) when the sub is executed from the CLI.
use POSIX qw(_exit);
sub execute {
# These 2 lines below were to eliminate the error that I mentioned before. It did not eliminated them just reduce them my $dbh = database(); $dbh->{InactiveDestroy} = 1;
my $pid = fork();
if ($pid) { # This is the parent (Dancer) in case you want to do something here debug “Process started with PID $pid\n”;
} elsif ($pid == 0) { # This is the child, here is where I do all I need $template = … $exit_code= …
print “Something in the console” if $cli _exit($exit_code); } else { debug “Could not fork: $!\n”; }
# I have a variable to know if I’m running this sub from the web or from CLI if ($cli) { my $output = waitpid($pid, 0); print “The process finish with output: $output”; }
return $template; }
On Jul 7, 2015, at 11:15 PM, Andrew Beverley <andy@andybev.com> wrote:
On 2015-07-08 00:58, Johandry Amador Segui wrote:
Hi Andy, I tried to use threads and it did not worked for me (maybe because of non safe thread modules I am using) so I use fork in a production application and it works good. I have some issues some times with MySQL that I have not fixed yet but they do not happen very often. This is an example of how I use it: sub execute { # These 2 lines below were to eliminate the error that I mentioned before. It did not eliminated them just reduce them my $dbh = database(); $dbh->{InactiveDestroy} = 1; my $pid = fork(); if ($pid) { # This is the parent (Dancer) in case you want to do something here debug “Process started with PID $pid\n”; } elsif ($pid == 0) { # This is the child, here is where I do all I need $template = ... } else { debug “Could not fork: $!\n”; } # I have a variable to know if I’m running this sub from the web or from CLI if ($cli) { my $output = waitpid($pid, 0); print “The process finish with output: $output”; } return $template; } This is just an example, not the entire code. If someone has a suggestion or improvement, it is welcome.
Surely you need an exit() in there somewhere for the child process, otherwise you'll end up with lots of web server threads?
Andy
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
participants (3)
-
Andrew Beverley -
Johandry Amador Segui -
Sawyer X