<commit_before>package JAGC::Task::check;
use Mojo::Base -base;

use File::Copy 'cp';
use File::Path 'remove_tree';
use File::Temp 'tempdir';
use Mango::BSON ':bson';
use Mojo::Util qw ( spurt encode);

sub prepare_container {
  my ($self, $app, $data, $sid, $lng) = @_;

  my @bin = ($lng->{path});
  push @bin, @{$lng->{args}} if $lng->{args};

  my $config = $app->config->{worker};
  my $log    = $app->log;

  # just checking if the container exists
  my $tx = $app->ua->get("$config->{api_server}/containers/solution_$sid/changes");
  return undef if $tx->success;

  my $tmp_dir = $self->{tmp_dir} = eval { tempdir DIR => $config->{shared_volume_dir} };
  $log->error("Can't create temp dir: $@") and return undef if $@;

  eval { spurt encode ('UTF-8', $data), "$tmp_dir/code" };
  $log->error("$@") and return undef if $@;

  $log->error("Can't copy starter: $!") and return undef
    unless cp $app->home->rel_file('script/starter'), $tmp_dir;

  $log->error("Can't set permissions for starter! $!") and return undef
    if 2 > chmod 0755, $tmp_dir, "$tmp_dir/starter";

  srand;
  my $opts = $config->{docker_opts};
  $opts->{User}  = (1024 + int rand 1024 * 10) . '';
  $opts->{Binds} = ["$tmp_dir:/opt/share"];
  push @{$opts->{Cmd}}, @bin;

  $tx = $app->ua->post("$config->{api_server}/containers/create?name=solution_$sid" => json => $opts);
  $log->error("Can't create container ". $tx->res->code ." ".$tx->res->body) and return undef unless $tx->success;

  $self->{container_id} = $tx->res->json->{Id};
  return 1;
}

sub destroy_container {
  my ($self, $app) = @_;

  remove_tree $self->{tmp_dir}, {error => \my $err};
  $app->log->warn("Can't remove directory $self->{tmp_dir}: " . $app->dumper($err)) if @$err;

  my $api_server = $app->config->{worker}{api_server};

  if (my $cid = $self->{container_id}) {
    my $tx = $app->ua->delete("$api_server/containers/$cid?v=1&force=1");
    return $app->log->error("Can't delete container '$cid'") unless $tx->success;
    $app->log->debug('Container was successfully destroyed!');
  }
}

sub run_test {
  my ($self, $app, $test) = @_;

  my $api_server = $app->config->{worker}{api_server};
  my $log        = $app->log;
  my $cid        = $self->{container_id};

  eval { spurt $test->{in}, "$self->{tmp_dir}/input" };
  $log->warn($@) and return undef if $@;

  $log->debug(sprintf 'Run test %s', $test->{_id});

  my $result;

  $app->ua->websocket(
    "$api_server/containers/$cid/attach/ws?stream=1&stdout=1" => sub {
      my ($ua, $tx) = @_;


      my $start_tx = $ua->post("$api_server/containers/$cid/start");

      $log->error("Can't start container! Status: " . $start_tx->res->body) and Mojo::IOLoop->stop
        unless $start_tx->success;

      $tx->on(finish => sub { $ua->post("$api_server/containers/$cid/stop?t=1"); Mojo::IOLoop->stop; });
      $tx->on(json => sub { my ($tx, $json) = @_; $result = $json; });
    }
  );
  Mojo::IOLoop->start;

  return $result;
}

sub call {<commit_msg>Failed tasks doesn't hang with 'testing' status anymore<commit_after>package JAGC::Task::check;
use Mojo::Base -base;

use File::Copy 'cp';
use File::Path 'remove_tree';
use File::Temp 'tempdir';
use Mango::BSON ':bson';
use Mojo::Util qw ( spurt encode);

sub prepare_container {
  my ($self, $app, $data, $sid, $lng) = @_;

  my @bin = ($lng->{path});
  push @bin, @{$lng->{args}} if $lng->{args};

  my $config = $app->config->{worker};
  my $log    = $app->log;

  # just checking if the container exists
  my $tx = $app->ua->get("$config->{api_server}/containers/solution_$sid/changes");
  return undef if $tx->success;

  my $tmp_dir = $self->{tmp_dir} = eval { tempdir DIR => $config->{shared_volume_dir} };
  $log->error("Can't create temp dir: $@") and return undef if $@;

  eval { spurt encode ('UTF-8', $data), "$tmp_dir/code" };
  $log->error("$@") and return undef if $@;

  $log->error("Can't copy starter: $!") and return undef
    unless cp $app->home->rel_file('script/starter'), $tmp_dir;

  $log->error("Can't set permissions for starter! $!") and return undef
    if 2 > chmod 0755, $tmp_dir, "$tmp_dir/starter";

  srand;
  my $opts = $config->{docker_opts};
  $opts->{User}  = (1024 + int rand 1024 * 10) . '';
  $opts->{Binds} = ["$tmp_dir:/opt/share"];
  push @{$opts->{Cmd}}, @bin;

  $tx = $app->ua->post("$config->{api_server}/containers/create?name=solution_$sid" => json => $opts);
  $log->error("Can't create container ". $tx->res->code ." ".$tx->res->body) and return undef unless $tx->success;

  $self->{container_id} = $tx->res->json->{Id};
  return 1;
}

sub destroy_container {
  my ($self, $app) = @_;

  remove_tree $self->{tmp_dir}, {error => \my $err};
  $app->log->warn("Can't remove directory $self->{tmp_dir}: " . $app->dumper($err)) if @$err;

  my $api_server = $app->config->{worker}{api_server};

  if (my $cid = $self->{container_id}) {
    my $tx = $app->ua->delete("$api_server/containers/$cid?v=1&force=1");
    return $app->log->error("Can't delete container '$cid'") unless $tx->success;
    $app->log->debug('Container was successfully destroyed!');
  }
}

sub run_test {
  my ($self, $app, $test) = @_;

  my $api_server = $app->config->{worker}{api_server};
  my $log        = $app->log;
  my $cid        = $self->{container_id};

  eval { spurt $test->{in}, "$self->{tmp_dir}/input" };
  $log->warn($@) and return undef if $@;

  $log->debug(sprintf 'Run test %s', $test->{_id});

  my $result;

  $app->ua->websocket(
    "$api_server/containers/$cid/attach/ws?stream=1&stdout=1" => sub {
      my ($ua, $tx) = @_;


      my $start_tx = $ua->post("$api_server/containers/$cid/start");

      $log->error("Can't start container! Status: " . $start_tx->res->body) and Mojo::IOLoop->stop
        unless $start_tx->success;

      $tx->on(finish => sub {
        unless( defined $result ) {
          my $err = defined $tx->error ? "ua: $tx->error->{message}" : 'unknown error';
          $result = {status => 'error', stderr => $err, stdout => ''};
        }

        $ua->post("$api_server/containers/$cid/stop?t=1"); Mojo::IOLoop->stop; 
      });
      $tx->on(json => sub { my ($tx, $json) = @_; $result = $json; });
    }
  );
  Mojo::IOLoop->start;

  return $result;
}

sub call {
{'fraction_non_alphanumeric': 0.22522088353413655, 'fraction_numerical': 0.007068273092369478, 'mean_word_length': 3.698867924528302, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 169, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1320813', 'n_tokens_mistral': 2430, 'n_tokens_neox': 2314, 'n_words': 510}