You can also pass a "return value" to the next step via the delay callback
(e.g. $end->($rows) => my ($delay, $rows) = @_). But the first argument is
left out unless you pass a 0 to $delay->begin, this is because most
non-blocking methods will pass their object as the first parameter. I tend
to use the delay data() more for things like timer IDs, or data not
specific to one step; you could store the timer ID this way after creating
the recurring timer. This is all just stylistic and for clarity of course.

On Wed, Apr 22, 2015 at 12:32 PM, hammondos <[email protected]> wrote:

> Thank you! For the record, this appears to do the job:
>
> my $r_id;
> $self->delay(
>     sub {
>         my $delay = shift;
>         my $end = $delay->begin;
>         $r_id = Mojo::IOLoop->recurring(
>             1 => sub {
>                 if (my $results = $sc_api->check_queue($report_id)) {
>                     my $rows = $sc_api->process_os($results);
>                     &_insert_data({domain => $domain, path => $path, data
> => {os => $rows}});
>                     $delay->data(rows => $rows);
>                     $end->();
>                 }
>             }
>         );
>     },
>     sub {
>         my $delay = shift;
>         Mojo::IOLoop->remove($r_id);
>         $self->render(json => $delay->data('rows'));
>     }
> );
>
>
>
> On Wednesday, 22 April 2015 15:15:22 UTC+1, Dan Book wrote:
>>
>> Also, to stop the recurring timer, save the returned id (you can store it
>> in the delay as well) and then remove it from the loop after a success (for
>> example in the next step).
>>
>> On Wed, Apr 22, 2015 at 10:14 AM, Dan Book <[email protected]> wrote:
>>
>>> You need to save the return value of $delay->begin, that returns a
>>> callback that you need to call in order to proceed to the next step, like
>>> in the timer example you were looking at before.
>>>
>>> On Wed, Apr 22, 2015 at 3:10 AM, hammondos <[email protected]> wrote:
>>>
>>>> Ok so I've adapted the script to use the delay helper, and based on the
>>>> documentation it seems like this should work, but still can't seem to exit
>>>> from the recurring loop.
>>>>
>>>> Feels like the placement of $delay->begin is wrong or I'm not using the
>>>> right signal to say the recurring loop should be stopped - return doesn't
>>>> seem right but have also tried $loop->stop & $loop->reset with no luck. Any
>>>> ideas?
>>>>
>>>> $self->delay(
>>>>     sub {
>>>>         my $delay = shift;
>>>>         $delay->begin;
>>>>         Mojo::IOLoop->recurring(
>>>>             1 => sub {
>>>>                 if (my $results = $sc_api->check_queue($report_id)) {
>>>>                     my $rows = $sc_api->process_os($results);
>>>>                     $log->info(Dumper($rows));
>>>>                     &_insert_data({domain => $domain, path => $path,
>>>> data => {os => $rows}});
>>>>                     $delay->data(rows => $rows);
>>>>                     return;
>>>>                 }
>>>>             }
>>>>         );
>>>>     },
>>>>     sub {
>>>>         my $delay = shift;
>>>>         $self->render(json => $delay->data('rows'));
>>>>     }
>>>> );
>>>>
>>>>
>>>>
>>>> On Tuesday, 21 April 2015 22:17:35 UTC+1, hammondos wrote:
>>>>>
>>>>> Ok cool, thanks for pointing me in the right direction
>>>>>
>>>>> On Tuesday, 21 April 2015 22:10:36 UTC+1, Dan Book wrote:
>>>>>>
>>>>>> Sort of. You want the delay helper here:
>>>>>> https://metacpan.org/pod/Mojolicious::Plugin::DefaultHelpers#delay
>>>>>>
>>>>>> That creates a Mojo::IOLoop delay as well, but also does all the
>>>>>> things I described before relevant to rendering. You won't be able to do 
>>>>>> a
>>>>>> recurring timer exactly the same way, as you can't set up begin() 
>>>>>> callbacks
>>>>>> in advance since you don't know how many there will be. You will want to
>>>>>> just create a recurring timer in the first step, get the callback from
>>>>>> $delay->begin, and you can have that call $end->() to proceed to the next
>>>>>> step when you get a success.
>>>>>>
>>>>>> On Tue, Apr 21, 2015 at 4:58 PM, hammondos <[email protected]>
>>>>>> wrote:
>>>>>>
>>>>>>> Great, thanks - so something like the code example from here
>>>>>>> <http://mojolicio.us/perldoc/Mojo/IOLoop#delay>? Not sure how to
>>>>>>> replace the timer with recurring logic though
>>>>>>>
>>>>>>> # Synchronize multiple eventsmy $delay = Mojo::IOLoop->delay(sub { say 
>>>>>>> 'BOOM!' });for my $i (1 .. 10) {
>>>>>>>   my $end = $delay->begin;
>>>>>>>   Mojo::IOLoop->timer($i => sub {
>>>>>>>     say 10 - $i;
>>>>>>>     $end->();
>>>>>>>   });}
>>>>>>> $delay->wait;
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Tuesday, 21 April 2015 21:41:48 UTC+1, Dan Book wrote:
>>>>>>>>
>>>>>>>> The finish event of the controller is not really appropriate here.
>>>>>>>> It will not fire until the transaction is finished, which doesn't 
>>>>>>>> happen
>>>>>>>> until you render a response. So once a success happens you want to call
>>>>>>>> something that will render a response from there. You probably want to 
>>>>>>>> use
>>>>>>>> the delay helper which will turn off automatic rendering, keep a 
>>>>>>>> reference
>>>>>>>> to the transaction, and handle exceptions.
>>>>>>>>
>>>>>>>> On Tue, Apr 21, 2015 at 3:39 PM, hammondos <[email protected]>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> I'm trying to run an AJAX call that needs to check an external API
>>>>>>>>> queue for a response every second, then generate a chart based on 
>>>>>>>>> that data
>>>>>>>>> using JSON.
>>>>>>>>>
>>>>>>>>> The code sample from the module I'm using to connect to the API
>>>>>>>>> suggests using a for...sleep loop, however clearly this doesn't work 
>>>>>>>>> with
>>>>>>>>> Mojolicious.
>>>>>>>>>
>>>>>>>>> I've tried several different permutations of using a recurring
>>>>>>>>> loop with varying degrees of success, but just can't get it to work -
>>>>>>>>> latest example below. This example never exits, even when there is 
>>>>>>>>> data
>>>>>>>>> returned.
>>>>>>>>>
>>>>>>>>> I'm aware that the $success parameter is probably not helping the
>>>>>>>>> situation, but would really appreciate any guidance on where to go 
>>>>>>>>> next to
>>>>>>>>> stop the loop once a successful response has been received, and 
>>>>>>>>> render a
>>>>>>>>> JSON response.
>>>>>>>>>
>>>>>>>>> my $success = 0;
>>>>>>>>> my $id = Mojo::IOLoop->recurring(
>>>>>>>>>     1 => sub {
>>>>>>>>>         $self->finish if $success == 1;
>>>>>>>>>         if (my $results = $sc_api->check_queue($report_id)) {
>>>>>>>>>             my $rows = $sc_api->process_os($results);
>>>>>>>>>             $log->info(Dumper($rows));
>>>>>>>>>             &_insert_data({domain => $domain, path => $path, data
>>>>>>>>> => {os => $rows}});
>>>>>>>>>             $success = 1;
>>>>>>>>>          }
>>>>>>>>>     }
>>>>>>>>> );
>>>>>>>>>
>>>>>>>>> # need to wait
>>>>>>>>> $self->on(finish => sub {
>>>>>>>>>     # remove ioloop
>>>>>>>>>     Mojo::IOLoop->remove($id);
>>>>>>>>>
>>>>>>>>>     my $db = $self->db;
>>>>>>>>>     my $analytics = $db->get_collection('analytics');
>>>>>>>>>     my $rows = $analytics->find({id => $url});
>>>>>>>>>     my $doc = $rows->next;
>>>>>>>>>     $self->render(json => $doc->{'analytics'}->{'os'});
>>>>>>>>> });
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  --
>>>>>>>>> You received this message because you are subscribed to the Google
>>>>>>>>> Groups "Mojolicious" group.
>>>>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>>>>> send an email to [email protected].
>>>>>>>>> To post to this group, send email to [email protected].
>>>>>>>>> Visit this group at http://groups.google.com/group/mojolicious.
>>>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>>>
>>>>>>>>
>>>>>>>>  --
>>>>>>> You received this message because you are subscribed to the Google
>>>>>>> Groups "Mojolicious" group.
>>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>>> send an email to [email protected].
>>>>>>> To post to this group, send email to [email protected].
>>>>>>> Visit this group at http://groups.google.com/group/mojolicious.
>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>
>>>>>>
>>>>>>  --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Mojolicious" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to [email protected].
>>>> To post to this group, send email to [email protected].
>>>> Visit this group at http://groups.google.com/group/mojolicious.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>
>>  --
> You received this message because you are subscribed to the Google Groups
> "Mojolicious" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/mojolicious.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/mojolicious.
For more options, visit https://groups.google.com/d/optout.

Reply via email to