Skip to content
Create a gist now

Instantly share code, notes, and snippets.

@kraih /
Last active

Embed URL


Subversion checkout URL

You can clone with
Download ZIP
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');
{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);
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->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;
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];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.