App-EvalServerAdvanced
view release on metacpan or search on metacpan
lib/App/EvalServerAdvanced/JobManager.pm view on Meta::CPAN
package App::EvalServerAdvanced::JobManager;
use v5.20;
use strict;
use warnings;
use feature qw(postderef);
no warnings qw(experimental::postderef);
our $VERSION = '0.024';
use Data::Dumper;
use Moo;
use App::EvalServerAdvanced::Config;
use App::EvalServerAdvanced::Log;
use Function::Parameters;
use POSIX qw/dup2 _exit/;
use IO::Handle;
has loop => (is => 'ro');
has workers => (is => 'ro', builder => sub {+{}});
has jobs => (is => 'ro', builder => sub {+{}});
method add_job($eval_obj) {
my $job_fut = $self->loop->new_future();
my $prio = $eval_obj->{priority} // "realtime";
debug "Got job, $prio";
my $job = {future => $job_fut, eval_obj => $eval_obj};
push $self->jobs->{$prio}->@*, $job;
$self->tick(); # start anything if possible
$job_fut->on_ready(sub {$self->tick()});
return $job;
}
method run_job($eval_job) {
my $eval_obj = $eval_job->{eval_obj};
my $job_future = $eval_job->{future};
my $out = '';
my $in = '';
my ($code_file) = grep {$_->filename eq '__code'} $eval_obj->{files}->@*;
my $code = $code_file->get_contents;
my $proc_future;
my $proc = IO::Async::Process->new(
code => sub {
close(STDERR);
dup2(1,2) or _exit(212); # Setup the C side of things
# *STDERR = \*STDOUT; # Setup the perl side of things
*STDERR = IO::Handle->new_from_fd(2, "w"); # setup a new STDERR
binmode STDOUT, ":encoding(utf8)"; # these really only affect perl subs, but they should also support other encodings
binmode STDERR, ":encoding(utf8)";
binmode STDIN, ":encoding(utf8)";
$SIG{$_} = sub {_exit(1)} for (keys %SIG);
eval {
App::EvalServerAdvanced::Sandbox::run_eval($code, $eval_obj->{language}, $eval_obj->{files});
};
if ($@) {
print "$@";
}
_exit(0);
},
stdout => {into => \$out},
# TODO these two things need to be handled differently for encoding
stdin => {from => Encode::encode("utf8", $in)},
on_finish => sub { my $out_utf8 = Encode::decode("utf8", $out); $job_future->done($out_utf8) unless $job_future->is_ready; delete $self->workers->{$proc_future}; }
);
( run in 0.533 second using v1.01-cache-2.11-cpan-39bf76dae61 )