Skip to content

Instantly share code, notes, and snippets.

@mpapec
Created May 28, 2016 19:50
Show Gist options
  • Save mpapec/7227391ecc4de09986ff8028d50146c1 to your computer and use it in GitHub Desktop.
Save mpapec/7227391ecc4de09986ff8028d50146c1 to your computer and use it in GitHub Desktop.
use 5.20.0;
use Mojolicious::Lite;
use Mojo::JSON qw(decode_json encode_json);
use Mojo::Redis2;
plugin 'DefaultHelpers';
app->config( hypnotoad => {
workers => 5,
# same as morbo
listen => ["http://*:3000"],
});
helper mystash => sub {
state $stash = {};
return $stash;
};
helper log => sub {
state $LOG = Mojo::Log->new;
return $LOG;
};
# errors are at odd indices
helper ioErr => sub {
my ($c, @arr) = @_;
# rethrow exception
die($arr[1]) if ref($arr[1]);
my $i = 0;
my $err = join "; ",
grep { $i++ %2 and $_ } @arr;
die({err => $err}) if $err;
};
helper redis => sub {
my ($c) = @_;
state $redis;
return $redis if $redis;
$redis = Mojo::Redis2->new;
my $msgHandler = sub {
my ($msg) = @_;
# handle requests
if (my $request = $msg->{request}) {
$msg->{response} = delete $msg->{request};
if ($request eq "getPID") {
$msg->{result} = $$;
}
return $msg if exists $msg->{result};
}
# handle responses
elsif (my $response = $msg->{response}) {
if ($response eq "getPID") {
my $arr = $c->mystash->{ $response } ||= [];
push @$arr, $msg;
}
return;
}
# nothing to do..
$c->log->warn("[$$] Don't understand ". $c->dumper($msg));
return;
};
my $redisEvents = {
# redis connection event
connection => sub {
my ($redis, $conn) = @_;
$c->log->info("[$$] Connected to redis! [$conn->{id}]");
},
# handle redis errors
error => sub {
my ($redis, $err) = @_;
$c->log->error($err);
},
# incoming redis messages
message => sub {
my ($redis, $msg, $node) = @_;
$c->log->debug("Incoming redis message for node $node: $msg");
my $resp = $msgHandler->(decode_json($msg)) or return;
$c->redis->publish($node, encode_json($resp), sub {});
},
};
#
$c->redis->on($_ => $redisEvents->{$_}) for keys %$redisEvents;
$c->redis->subscribe(["WORKERS"], sub {
my ($self, $err, $res) = @_;
$c->log->error("error on redis subscribe: $err") if $err;
$c->log->debug("[$$] subscribed!") if !$err;
});
return $redis;
};
get '/__status' => sub {
my ($c) = @_;
my $req = {request => "getPID"};
delete $c->mystash->{ $req->{request} };
Mojo::IOLoop->delay(
sub {
my ($d, $err) = @_;
$c->redis->publish("WORKERS", encode_json($req), $d->begin);
Mojo::IOLoop->timer(2 => $d->begin);
},
sub {
my ($d) = @_;
$c->ioErr(@_);
$c->render(json => {
me => $$,
report => delete $c->mystash->{ $req->{request} }
});
# $c->$cb(undef, my $ok=1);
},
)
# ->catch(sub{ $c->$cb($@) })
;
};
app->redis;
app->start;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment