Skip to content

Instantly share code, notes, and snippets.

@marioroy
Last active March 23, 2016 14:06
Show Gist options
  • Save marioroy/3c8aa2c373873adf172a to your computer and use it in GitHub Desktop.
Save marioroy/3c8aa2c373873adf172a to your computer and use it in GitHub Desktop.
Dancer2 + MCE / MCE::Hobo + MCE::Shared demonstrations
package MyDancer2App;
use strictures 1;
BEGIN {
our $VERSION = '0.001';
}
use Dancer2;
use Time::HiRes 'time';
use MCE Sereal => 1;
use MCE::Shared Sereal => 1;
use MCE::Shared::Hash;
# http://127.0.0.1:3000/?N=200 # Increase N for longer processing time
# http://127.0.0.1:3000/?N=80000000 # Notice parallelism via top display
BEGIN {
set content_type => 'text/plain';
}
my $cache = MCE::Shared::Hash->new(); # non-shared hash
my $seq = MCE::Shared->sequence(); # shared sequence
my $pi = MCE::Shared->scalar(); # shared scalar
sub compute_pi {
my ( $mce ) = @_;
my ( $N ) = $mce->user_args()->[0];
while ( my ( $beg, $end ) = $seq->next ) {
my ( $_pi, $t ) = ( 0.0 );
for my $i ( $beg .. $end ) {
$t = ( $i + 0.5 ) / $N;
$_pi += 4.0 / ( 1.0 + $t * $t );
}
$pi->incrby( $_pi );
}
return;
}
my $mce = MCE->new(
max_workers => 4,
user_func => \&compute_pi,
posix_exit => 1,
)->spawn();
get '/' => sub {
delayed {
my $N = params->{'N'} //= 4_000_000;
my $start = time();
if ( ! $cache->exists( $N ) ) {
$seq->rewind( { chunk_size => 200_000, bounds_only => 1 }, 0, $N - 1 );
$pi->set( 0.0 );
# 0 = MCE workers persist after running
$mce->run( 0, { user_args => [ $N ] } );
$cache->set( $N, sprintf(
"pi = %0.13f, duration = %0.03f seconds",
$pi->get() / $N, time() - $start
));
}
content $cache->get( $N );
done;
};
};
dance;
package MyDancer2App;
use strictures 1;
BEGIN {
our $VERSION = '0.001';
}
use Dancer2;
use Time::HiRes 'time';
use MCE::Hobo Sereal => 1;
use MCE::Shared Sereal => 1;
use MCE::Shared::Hash;
# http://127.0.0.1:3000/?N=200 # Increase N for longer processing time
# http://127.0.0.1:3000/?N=80000000 # Notice parallelism via top display
BEGIN {
set content_type => 'text/plain';
}
my $cache = MCE::Shared::Hash->new(); # non-shared hash
my $seq = MCE::Shared->sequence(); # shared sequence
my $pi = MCE::Shared->scalar(); # shared scalar
sub compute_pi {
my ( $N ) = @_;
while ( my ( $beg, $end ) = $seq->next ) {
my ( $_pi, $t ) = ( 0.0 );
for my $i ( $beg .. $end ) {
$t = ( $i + 0.5 ) / $N;
$_pi += 4.0 / ( 1.0 + $t * $t );
}
$pi->incrby( $_pi );
}
return;
}
get '/' => sub {
delayed {
my $N = params->{'N'} //= 4_000_000;
my $start = time();
if ( ! $cache->exists( $N ) ) {
$seq->rewind( { chunk_size => 200_000, bounds_only => 1 }, 0, $N - 1 );
$pi->set( 0.0 );
for ( 1 .. 4 ) {
MCE::Hobo->create( { posix_exit => 1 }, \&compute_pi, $N );
}
# ... do other stuff ...
$_->join() for MCE::Hobo->list();
$cache->set( $N, sprintf(
"pi = %0.13f, duration = %0.03f seconds",
$pi->get() / $N, time() - $start
));
}
content $cache->get( $N );
done;
};
};
dance;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment