Skip to content

Instantly share code, notes, and snippets.

@punytan
Created July 28, 2012 18:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save punytan/3194362 to your computer and use it in GitHub Desktop.
Save punytan/3194362 to your computer and use it in GitHub Desktop.
use strict;
use warnings;
use AE;
use AnyEvent::HTTP;
use Twiggy::Server;
use Plack::Request;
use Plack::Session;
use Plack::Builder;
use JSON;
use Time::HiRes ();
use Log::Minimal;
local $Log::Minimal::AUTODUMP = 1;
local $AnyEvent::HTTP::MAX_PER_HOST = 10000;
my $clients = {};
my $app = sub {
my $req = Plack::Request->new(shift);
my $client_id = Plack::Session->new($req->env)->{options}{id};
$clients->{$client_id} ||= {
cv => AE::cv,
};
unless ($req->env->{'psgi.nonblocking'}) {
die "non-supported server";
}
return sub {
my $respond = shift;
my @response_buffer;
my $start_time = Time::HiRes::time;
my $cb = sub {
my $res = [
200,
['Content-Type' => 'text/plain'],
[
JSON->new->pretty(1)->encode({
Runtime => Time::HiRes::time - $start_time,
Response => \@response_buffer
})
]
];
return $respond->($res);
};
$clients->{$client_id}{cv}->cb(sub {
infof \@_;
$cb->( $_[0]->recv );
});
my @waits = $req->path_info =~ /(\d+).(\d+).(\d+)/;
for my $wait (@waits) {
$clients->{$client_id}{cv}->begin;
infof "Requested: $wait";
http_get "http://localhost:6000/$wait", timeout => 60, sub {
my $res = decode_json(shift);
infof $res;
push @response_buffer, $res;
$clients->{$client_id}{cv}->end;
};
}
};
};
my $server = Twiggy::Server->new( port => 7000 );
$server->register_service(builder { enable "Session"; $app} );
AE::cv->recv;
package LazyServer;
use strict;
use warnings;
use parent 'Tatsumaki::Handler';
__PACKAGE__->nonblocking(1);
use Time::HiRes ();
use Log::Minimal;
local $Log::Minimal::AUTODUMP = 1;
sub get {
my $self = shift;
my $sec = $self->args->[0];
infof "New request: $sec seconds";
my $now = Time::HiRes::time;
my $t; $t = AE::timer $sec, 0, $self->async_cb(sub {
$self->on_event(@_, $now);
undef $t;
});
}
sub on_event {
my $self = shift;
my $now = pop;
my $elapsed = Time::HiRes::time - $now;
my $res = { wait => $elapsed };
infof $res;
$self->write($res);
$self->finish;
}
package main;
use strict;
use warnings;
use AE;
use Twiggy::Server;
use Tatsumaki::Application;
my $app = Tatsumaki::Application->new( [ '/(\d+)' => 'LazyServer' ]);
my $server = Twiggy::Server->new( port => 6000 );
$server->register_service($app->psgi_app);
AE::cv->recv;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment