Skip Menu |

This queue is for tickets about the IO-Async CPAN distribution.

Report information
The Basics
Id: 91648
Status: resolved
Priority: 0/
Queue: IO-Async

People
Owner: Nobody in particular
Requestors: drrho [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: (no value)



Subject: IO::Async::Channel misses length functionality
I strongly miss a way to determine whether a channel has messages in it. ->recv in sync mode will block, but there are situations where you want to check the channel, and if there is nothing in it, you move on with your life. Unless I missed it, of course :-) rgds, \rho PS: This is on the critical path for me, whether to use IO::Async, or not. And I really like the design (although it would profit from moving to Moose roles).
On Wed Dec 25 03:32:06 2013, DRRHO wrote: Show quoted text
> I strongly miss a way to determine whether a channel has messages > in it. ->recv in sync mode will block, but there are situations where > you want to check the channel, and if there is nothing in it, you move > on with your life.
Hmm. The question I suppose is how to handle the message reading properly, because you can't just atomically read() an entire message. I could quite easily add a simple select() wrapper around the read(), so if there was no message waiting the wrapper would return undef, or if select() said the filehandle was read-ready it could wait reading the entire message. This however would still block while the message was being read. If the message was quite big it could be that the main process still hasn't written all of it yet. I guess the next step up from here would be having the read wrapper continue to return undef until an entire message has been read. This would require some kind of buffer. At which point we're starting to rebuild a micro event system on the Routine side of the Channel. I start to wonder whether in your case, your program may be better served by running another IO::Async::Loop within the child process side. What's the use-case surrounding this? This doesn't sound like the simple kind of Channel+Routine used to asynchronise some kind of synchronous function call. Perhaps something larger may help here..? -- Paul Evans
CC: drrho [...] cpan.org
Subject: Re: [rt.cpan.org #91648] IO::Async::Channel misses length functionality
Date: Sat, 4 Jan 2014 11:11:43 +0100
To: Paul Evans via RT <bug-IO-Async [...] rt.cpan.org>
From: Robert Barta <rho [...] devc.at>
On Wed, Dec 25, 2013 at 11:34:26AM -0500, Paul Evans via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=91648 > > > On Wed Dec 25 03:32:06 2013, DRRHO wrote:
> > I strongly miss a way to determine whether a channel has messages > > in it. ->recv in sync mode will block, but there are situations where > > you want to check the channel, and if there is nothing in it, you move > > on with your life.
Show quoted text
> Hmm. The question I suppose is how to handle the message reading > properly, because you can't just atomically read() an entire > message.
Yes, that does not fit nicely into the async programming paradigm. Show quoted text
> At which point we're starting to rebuild a micro event system on the > Routine side of the Channel. I start to wonder whether in your case, > your program may be better served by running another IO::Async::Loop > within the child process side.
Unfortunately that is not an option (recursive structure). Show quoted text
> What's the use-case surrounding this? This doesn't sound like the > simple kind of Channel+Routine used to asynchronise some kind of > synchronous function call. Perhaps something larger may help here..?
Use case is task scheduling: I have a scheduler which runs large computations in an optimized order. In-between the transitions the web server should serve any outstanding requests. In a nutshell I want something like this: sub _compute_when_idle { my $code = shift; my $fu = $loop->new_future; my $co = sub { &$code () ; $fu->done }; $loop->later ( $co ); $loop->await ($fu); } map { my $id = $_; _compute_when_idle ( sub { warn "long synchronous computation $id"; sleep 2; } ) } ( 'aaa', 'bbbb', 'ccccccc', 'ddddd' ); # transitions This actually works if there is only a timer in the $loop: # create $timer $loop->add( $timer ); But ->later seems to completely ignore incoming HTTP when # create $httpserver $loop->add( $httpserver ); is added instead. \rho PS: I cannot fork() as transitions are transactional on a larger in-memory structure.
On Sat Jan 04 04:57:02 2014, rho@devc.at wrote: Show quoted text
> PS: I cannot fork() as transitions are transactional on a larger in- > memory structure.
I have removed this/my restriction and everything (except the max_workers issue) works as advertised. \rho