user2145475
user2145475

Reputation: 657

Mojolicious - two non-blocking GET requests in the same controller

I'm writing a Mojolicious module/controller that needs to make two GET requests; one after the other. The second GET request depends on response data from the first.

I would like both requests to be non-blocking. However I can't easily "return" from the context of the first non-blocking callback to supply values to the second request.

sub my_controller {

    my ($self) = @_;

    $self->ua->get($first_endpoint, sub {
        # handle response - extract value for second request?
    }); 

    my $second_endpoint = 'parameter not available here';

    $self->ua->get($second_endpoint, sub {}); 

}

I would prefer not to nest the second request into the first callback if possible?

Upvotes: 2

Views: 346

Answers (1)

Logioniz
Logioniz

Reputation: 891

First need to call render_later method in controller because you write non-blocking code.

Exist 2 ways how to pass data:

1)

sub  action_in_controller {
  my $c = shift->render_later;

  $c->delay(
    sub {
      my $delay = shift;

      $c->ua->get('http://one.com' => $delay->begin);
    },
    sub {
      my ($delay, $tx) = @_;

      $c->ua->post('http://second.com' => $delay->begin);
    },
    sub {
      my ($delay, $tx) = @_;

      $c->render(text => 'la-la-la');
    }
  );
}

2)

sub action_in_controller {
  my $c = shift->render_later;

  $c->ua->get('http://one.com' => sub {
    my ($ua, $tx) = @_;

    $c->ua->post('http://second.com' => sub {
      my ($ua, $tx) = @_;

      $c->render(text => 'la-la-la');
    });
  });
}

UPD

Found another variant of calling using Coro. But in perl 5.22 it not work and need to apply patch to repair it. You need additionally to write plugin Coro. Here example. You need only ua.pl and plugin Mojolicious::Plugin::Core.

Upvotes: 1

Related Questions