Skip to content

Instantly share code, notes, and snippets.

@kraih
Last active April 19, 2019 13:48
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kraih/6082061 to your computer and use it in GitHub Desktop.
Save kraih/6082061 to your computer and use it in GitHub Desktop.
use Mojolicious::Lite;
use Mango;
use Mango::BSON ':bson';
plugin 'Coro';
my $uri = 'mongodb://<user>:<pass>@<server>/<database>';
helper mango => sub { state $mango = Mango->new($uri) };
# Store and retrieve information non-blocking without using callbacks
get '/' => sub {
my $self = shift;
# Store information about current visitor
my $collection = $self->mango->db->collection('visitors');
$collection->with::coro::insert(
{when => bson_time, from => $self->tx->remote_address});
# Retrieve information about previous visitors
my $cursor = $collection->find->sort({when => -1})->fields({_id => 0});
my $docs = $cursor->with::coro::all;
# And show it to current visitor
$self->render(json => $docs);
};
app->start;
package Mojolicious::Plugin::Coro;
use Mojo::Base 'Mojolicious::Plugin';
use Coro;
use Mojo::IOLoop;
# Wrap application in coroutine and reschedule main coroutine in event loop
sub register {
my ($self, $app) = @_;
my $subscribers = $app->plugins->subscribers('around_dispatch');
unshift @$subscribers, sub {
my $next = shift;
async { $next->() };
};
$app->plugins->unsubscribe('around_dispatch');
$app->hook(around_dispatch => $_) for @$subscribers;
Mojo::IOLoop->recurring(0 => sub {cede});
}
# Magical class for calling a method non-blocking without a callback and
# rescheduling the current coroutine until it is done
package with::coro;
use Coro;
sub AUTOLOAD {
my ($method) = our $AUTOLOAD =~ /^with::coro::(.+)$/;
my ($done, $err, @args);
shift->$method(@_ => sub { $done++; shift; $err = shift; @args = @_ });
cede until $done;
die $err if $err;
return wantarray ? @args : $args[0];
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment