Async iterators

Clinton Gormley clint at traveljury.com
Mon Aug 6 15:03:49 CEST 2012


Hi all

I'm a bit clueless about event-driven programming, but I've had requests
to support AE in my ElasticSearch modules, eg 
https://metacpan.org/module/ElasticSearch::Transport::AEHTTP

Currently, I'm trying to convert 
https://metacpan.org/module/ElasticSearch::ScrolledSearch to be
non-blocking. 

In summary, this module is an iterator over an internal buffer that
gets filled up on demand with async http requests.  In sync style, it'd
be used like this:

    $s = ElasticSearch::ScrolledSearch->new(@args);
    while ($n = $s->next) {
        do_something;
    }
    
I could also say: 

    @docs = $s->next(100)

next() checks if there are sufficient docs in the buffer to satisfy the
request and if not, calls refill_buffer() and loops to check again.

My first attempt at converting this module looks like this:

https://gist.github.com/3274257

The problem I have is that I don't see how to achieve this functionality
without having some way of yielding to the event loop.  Specifically:

https://gist.github.com/3274257#L65

I know that I shouldn't be calling AnyEvent->_poll() but I don't know
how I should be approaching this.  

One suggestion that was made to me was to expose something like:

    $cv = $s->ensure_buffer_is_ready;
    
which would allow the user to decide how to block, poll whatever, but
this feels like I'm leaking implementation details.

It may be that the interface to an event-driven iterator should be 
completely different. I assume that there are well known patterns for
doing this kind of thing in the async world, but I've not had much
success in finding them.

Any pointers gratefully received

thanks

Clint





More information about the anyevent mailing list