Replies: 3 comments 3 replies
-
You should never sleep or perform a similar long blocking operation in a Mojolicious program as it will block the worker from responding to other requests. You can use a subprocess to perform a task in a forked process asynchronously, thus allowing the action to return and complete the response, but after-response jobs are ideally handled by a separate job queue process. Minion is a job queue with great Mojolicious integrations. |
Beta Was this translation helpful? Give feedback.
-
Following up on this response - in investigating subprocesses, I tried the sample subprocess code: my $subprocess = Mojo::IOLoop::Subprocess->new; The syntax looked strange to my old-fashioned Perl eyes, but I thought "Okay, maybe this works nowadays..." Using Perl 5.16 this generates the following compile errors: Illegal character in prototype for ? : $subprocess at setupTransfer.pl line 6239. So I built subs for the subprocess and callback: $c->stash("progressLog" => $progressLog); my $err; my $subprocess = Mojo::IOLoop::Subprocess->new; This works - as in the subprocess executes and exits - but the page doesn't render until after the subprocess finishes. Furthermore, the callback executes, but reports an error, (Use of uninitialized value $parent in method lookup at /usr/local/share/perl5/Mojo/IOLoop/Subprocess.pm line 85.) but since I don't want a callback anyway, that is only of academic interest. To recap - I would like the page to render snappily, and the subprocess to scutter off and finish at its leisure. Instead, the subprocess scutters off, and the page doesn't render until it returns. Obviously, I don't understand how to make suprocesses behave correctly, but I'm hoping you can enlighten me. I tried just fork'ing a child, which behaves as desired, but there seems to be no way to clean up the child process (the parent can't waitpid without hanging). I can guess that monkeying with fork'ed subprocesses with IOLoop handling an event loop is probably bad manners, anyway. I realize that Minion should solve my problem, but I would prefer to avoid adding that dependency and additional infrastructure to accomplish something that seems like it should be achievable with Mojolicious on its own. Thanks for your attention, Joe Fridy |
Beta Was this translation helpful? Give feedback.
-
Thank you - my code performs as desired, and I am slightly enlightened. Regards, Joe Fridy |
Beta Was this translation helpful? Give feedback.
-
I have a long running task that a user initiates. I would like to immediately respond to the request, and then proceed to complete the task in the background. In this simplistic example, the "sleep 60;" is filling in for the long task:
any '/publicKey' => sub {
my $c = shift;
my $publicKey =
gpg --armor --export $FromAddress
;$c->render(text => "
");sleep(60);
};
When I ask for a publicKey, it doesn't display for 60 seconds, despite the sleep being after the render.
I assume that it is possible to send the response, and then proceed with computations unrelated to the response.
But thus far, the way to do this eludes me. Adding $c->rendered did not accomplish my objective. Neither did converting
to $c->write, followed by $c->finish.
Please advise.
Beta Was this translation helpful? Give feedback.
All reactions