-
-
Save dotandimet/495249522e22405a7d0b729cabacce09 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package LongQuery; | |
use Mojo::Base '-base'; | |
use utf8; | |
use Mojo::Util qw(dumper); | |
use String::Util qw(crunch); # Mojo::Util::squish got dropped :( | |
use Mojo::UserAgent; | |
use Mojo::Log; | |
has ua => sub { Mojo::UserAgent->new( max_redirects => 5 ) }; | |
has log => sub { Mojo::Log->new }; | |
sub query { | |
my ($self, $type, $seq) = @_; | |
my $delay = Mojo::IOLoop->delay( | |
sub { | |
$self->log->info("starting session..."); | |
$self->ua->get( $self->start_url, shift->begin ); | |
}, | |
sub { | |
my ($delay, $tx) = @_; | |
$self->check_tx($tx); | |
$delay->pass; | |
}, | |
sub { | |
my $delay = shift; | |
$self->log->info("submitting sequence search..."); | |
$self->ua->post( $self->search_url, | |
form => $self->search_params($type, $seq), | |
$delay->begin ); | |
}, | |
sub { | |
my ($delay, $tx) = @_; | |
$self->check_tx($tx); | |
my $job_id = $tx->res->body; | |
$self->log->info("search created with job id: $job_id"); | |
$delay->data(job_id => $job_id); | |
$delay->pass($job_id); | |
}, | |
sub { | |
my ($delay, $job_id) = @_; | |
$self->ua->get( $self->query_info_url($job_id), $delay->begin ); | |
}, | |
sub { | |
my ($delay, $tx) = @_; | |
$self->check_tx($tx); | |
$self->log->info("Query Info: " . $tx->res->text); | |
my $query_info = $tx->res->json; | |
$delay->data(query_info => $query_info); | |
$delay->ioloop->timer(2 => $delay->begin); # wait a bit... | |
}, | |
sub { | |
my $delay = shift; | |
my $job_id = $delay->data('job_id'); | |
$self->wait_job($job_id, $delay->begin(0)); | |
}, | |
sub { | |
my ($delay, $err, $job_id) = @_; | |
die $err if (defined $err); | |
# get results! | |
$self->ua->post( $self->result_url($job_id), | |
json => { "filter" => {}, "limit" => 25, "offset" => 0 }, | |
$delay->begin ); | |
}, | |
sub { | |
my ($delay, $tx) = @_; | |
$self->check_tx($tx); | |
my $result = $tx->res->json; | |
$self->log->info( "Got results: " . dumper $result); | |
$delay->data('results' => $result); | |
} | |
} | |
)->catch( | |
sub { | |
my $delay = shift; | |
$self->log->fatal("Operation Failed: ", @_); | |
} | |
)->wait(); | |
return $delay->data; | |
}; | |
sub wait_job { | |
my ( $self, $job_id, $cb ) = @_; | |
$self->ua->get( | |
$self->status_url($job_id), # url | |
$self->check_job_state($job_id, $cb) # callback | |
); | |
} | |
sub check_job_state { | |
my ($self, $job_id, $cb) = @_; | |
return sub { | |
my ($tx) = pop @_; | |
my ($err, $timer, $job_state); | |
eval { | |
$self->check_tx($tx); | |
$job_state = $tx->res->json->{'state'}; | |
} or ($err = $@); | |
if ($job_state) { | |
if ($job_state eq 'PROCESSING') { | |
$timer = Mojo::IOLoop->timer( 2 => sub { $self->wait_job($job_id, $cb); } ); | |
} | |
elsif ($job_state eq 'FAILURE') { | |
$err = "job $job_id failed: " . $tx->res->json->{description}; | |
} | |
elsif ($job_state eq 'COMPLETE') { | |
$self->log->info("finished $job_id!"); | |
} | |
else { | |
$self->log->error("unrecognized job state: $job_state"); | |
$err = "unrecognized job state $job_state"; | |
} | |
} | |
unless ($timer) { # we either failed or finished | |
$cb->($err, $job_id); | |
} | |
}; | |
} | |
sub failed { | |
my ($self, $tx) = @_; | |
my $err = $tx->error; | |
my $url = $tx->req->url; | |
my ($msg) = ($err->{code}) ? "$err->{code} response: $err->{message} on URL $url" | |
: "Connection error: $err->{message} on URL $url"; | |
$self->log->fatal($msg); | |
return $msg; # No Mr. Bond, I expect you to die | |
}; | |
sub debug { | |
my ($self, $tx) = @_; | |
$self->log->debug( "Got: code " | |
. $tx->res->code | |
. " content: " | |
. $tx->res->text | |
. " headers: " | |
. dumper($tx->res->headers->to_hash) ); | |
} | |
sub check_tx { | |
my ($self, $tx) = @_; | |
$self->debug($tx) if (DEBUG); | |
die $self->failed($tx) if ($tx->error); | |
} | |
# several methods snipped (mostly those that return URLs) | |
#... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment