On Sun, Jun 21, 2009 at 06:17:51PM +0600, mikhail maluyk 
<[email protected]> wrote:
> I have a few classes. Each has associated storage class. Now when some event
> happens (like terminal input), i want to read data from all storage classes
> available (or not all, want to make this configurable really). I'm using
> AnyEvent::AIO for readings. Here is an example code, which i need to sync
> somehow (using timer event is just an example).

If you do not want to read all files in parallel (sequentially might
actually be faster than reading them in parallel and of course also makes
it easy to keep the order), you can use Coro and Coro::AIO:

   ... cb => Coro::unblock_sub {
      for my $storage (@storages) {
         Coro::AIO::aio_load $storage->file, my $buf
            and die "path: $!";
         $data .= $buf;
      }
   });

If you want to read them in parallel in any order, use an aio_group, whose
clalback will be invoked once all requests are done:

   my $grp = aio_group { say "data has been read: $data" };

   for my $storage (@storages) {
      my $buf;
      add $grp aio_load $storage->file, $buf, sub {
         $_[0] and die...;
         $data .= $buf;
      };
   }

You can also use a group, and a feeder. If the feeder limit is 1, you get
a strict ordering, if it is larger than 1, you read that many files in
parallel, allowing fine-grained control over parallelity:

   my $grp = aio_group { say "data has been read: $data" };
   limit $grp 1;
   feed $grp sub {
      my $next = shift @storages;
      add $_[0] aio_load ...;
   };

> I think it's clear why it's not working.. I was trying to use condvar->send
> , condvar->recv with no success, because i don't know how to determine where
> from call condvar->send, it seems that it should be called after the last

Oh, easy, pipeline it (note that this preserves ordering, even though all
files are being read in parallel. note also that this is not event-driven,
but blocking, so not useful in a callback).

  my $data =
     join "",
     map $_->recv,
     map {
        my $cv = AnyEvent->condvar;
        my $buf;
        aio_load $_->file, $buf, sub { $cv->send ($buf) };
        $cv
     } @storages;

(all the examples are untested...)

Hope that helps,

-- 
                The choice of a       Deliantra, the free code+content MORPG
      -----==-     _GNU_              http://www.deliantra.net
      ----==-- _       generation
      ---==---(_)__  __ ____  __      Marc Lehmann
      --==---/ / _ \/ // /\ \/ /      [email protected]
      -=====/_/_//_/\_,_/ /_/\_\

_______________________________________________
libev mailing list
[email protected]
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev

Reply via email to