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] <javascript:>
> > 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] 
>> <javascript:>> 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] <javascript:>.
>>> To post to this group, send email to [email protected] 
>>> <javascript:>.
>>> 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