Posting with useragent after rendering

61 views
Skip to first unread message

Iván Aponte

unread,
Apr 26, 2016, 7:57:17 PM4/26/16
to Mojolicious
 Hello, 

I have the following problem. I have a service which gets call, it must answer with 200, close the connection and post to another web service. If I do it in a non-blocking way premature closing occurs. 

E.g. : 

sub res1{
  my $c=shift;
   $c->render(status=>200,data=>'');
   my $ua = Mojo::UserAgent->new;
   my $tx = $ua->build_tx(POST => 'http//www.example.com');
   $ua->start($tx=> sub{
    my ($uax, $txx) = @_;
     $c->app->log->debug(Dumper($txx));
   });
}



Is there a way to make a post after rendering without blocking ?


Thanks, 

IA

Scott Wiersdorf

unread,
Apr 26, 2016, 8:09:19 PM4/26/16
to Mojolicious
Is there a reason you can't do something like this?:

sub res1{
  my $c=shift;
  $c->ua->post('http://www.example.com', sub {
    my ($uax, $txx) = @_;
     $c->app->log->debug(Dumper($txx));
  });

  $c->render(status=>200,data=>'');
}

The way you're doing it, the transaction goes out of scope which is probably why you get the premature connection close. In the above example, the post() will return immediately, allowing the render() to execute next. The post() response will be handled asynchronously whenever it comes back. 

Scott

Iván Aponte

unread,
Apr 26, 2016, 8:29:48 PM4/26/16
to Mojolicious
Hello,

I just tried the way you suggest but got the same error. Seems to me that UA goes out of scope and dies. Is there a way to prevent this

Regards, 

IA

Scott Wiersdorf

unread,
Apr 26, 2016, 11:01:10 PM4/26/16
to Mojolicious
No, the UA here is part of the controller object that doesn't go out of scope. You're doing something else wrong but we can't see it from here.

In terminal 1, example.pl:
#!/usr/bin/env perl
use Mojolicious::Lite;

post '/' => sub {
  my $c = shift;
  $c->render(json => {message => "worked"});
};

app->start;

$ ./example.pl daemon -l "http://*:3000"

In terminal 2, caller.pl:
#!/usr/bin/env perl
use Mojolicious::Lite;

get '/' => sub {
    my $c = shift;
    $c->ua->post(
        'http://localhost:3000',
        sub {
            my ($ua, $tx) = @_;
            $c->app->log->debug($c->app->dumper($tx->res->json));
        }
    );

    $c->render(status => 200, data => "thanks");
};

app->start;


In a 3rd terminal:


Logs for example:
$ ./example daemon -l "http://*:3000"
[Tue Apr 26 20:58:33 2016] [info] Listening at "http://*:3000"
Server available at http://127.0.0.1:3000
[Tue Apr 26 20:58:36 2016] [debug] POST "/"
[Tue Apr 26 20:58:36 2016] [debug] Routing to a callback
[Tue Apr 26 20:58:36 2016] [debug] 200 OK (0.000603s, 1658.375/s)

Logs for caller.pl:

$ ./caller daemon -l "http://localhost:3001"
[Tue Apr 26 20:56:44 2016] [info] Listening at "http://localhost:3001"
Server available at http://localhost:3001
[Tue Apr 26 20:58:36 2016] [debug] GET "/"
[Tue Apr 26 20:58:36 2016] [debug] Routing to a callback
[Tue Apr 26 20:58:36 2016] [debug] 200 OK (0.000994s, 1006.036/s)
[Tue Apr 26 20:58:36 2016] [debug] {
  "message" => "worked"
}

Working as advertised.

Scott

Iván Aponte

unread,
Apr 27, 2016, 9:28:45 AM4/27/16
to Mojolicious
Hello, 

Thanks. The error was that I was creating my own UserAgent and not using the helper in the controller.

Jan Henning Thorsen

unread,
Apr 28, 2016, 8:34:52 AM4/28/16
to Mojolicious
Ivan: It's not a safe thing to do "something else" after the request has been sent to the client. At least not if you use hypnotoad / prefork. The reason for this is that the children gets recycled from time to time, and doing that might kill the outgoing request.

I would much rather suggest putting minion or some other queue system in the middle which can handle the slow requests.

Matija Papec

unread,
Apr 29, 2016, 9:24:06 AM4/29/16
to Mojolicious

As for children recycling, could it happen when the child has open websocket connection?


regards

Iván Aponte

unread,
May 1, 2016, 11:11:24 AM5/1/16
to Mojolicious
Didn't know about minion. I will check it out. 

Thanks ,

IA
Reply all
Reply to author
Forward
0 new messages