- Added IO::Async::FileStream. This behaves like a read-only IO::Async::Stream, but reads its data from a regular file on the filesystem. Like tail -f, or File::Tail, it watches the file for changes in size, and follows appended data.
- Added IO::Async::Function. This is a true IO::Async::Notifier subclass to represent an asynchronous block of code; which was previously handled by DetachedCode. Being a true Notifier subclass gives it many advantages, and should provide a better base to build other things on. IO::Async::Resolver is now a subclass of Function, not DetachedCode.
- Added IO::Async::Process. This is another IO::Async::Notifier subclass, this time to represent an external process.
- Support encoding parameter in IO::Async::Stream. This allows the Stream to handle text in some encoding, rather than simply raw bytes.
- Support first_interval parameter to IO::Async::Timer::Periodic. If supplied, this will be the first wait time when the timer is started. In particular, if it is zero the timer's first invocation will happen immediately.
- Allow Loop->listen to be extended via extensions, similar to ->connect. Such extensions as IO::Async::SSL are already set up to make use of this.
- Distribution now uses Test::Fatal rather than Test::Exception. The former is smaller and simpler, whereas the latter relies on clever tricks to hack on caller(), which sometimes breaks some setups.
- Added convenient method in IO::Async::Loop for handling socket addresses; extract_addrinfo. This recognises strings for common networking constants; 'inet', 'inet6' and 'unix' as socket families, 'stream', 'dgram' and 'raw' as socket types. These convenient forms are also recognised by the ->connect and ->listen methods.
- Now prefers to use the IPv6 support functions found in Perl 5.14's Socket module; only falling back to using Socket::GetAddrInfo in earlier perls.
My thoughts, ideas, and sometimes rants, on Perl, C, Linux, terminals,...
Showing posts with label IO::Async::SSL. Show all posts
Showing posts with label IO::Async::SSL. Show all posts
2011/06/20
Perl - IO::Async - version 0.41
Wow; seems I haven't been writing these posts as much as I should be. I last wrote about version 0.34, and just now I've uploaded version 0.41 to CPAN. Quite a bit changed between then and now, here's a rundown of the most important bits:
Labels:
cpan,
IO::Async,
IO::Async::SSL,
IPv6,
perl,
Socket,
Socket::GetAddrInfo,
Test::Fatal
2010/07/01
Good code, bad tests
I've been working on IO::Async::SSL recently. Both the previous upload, and the next one I shall shortly do, are fixes for failing smoke tests. Moreover, they're fixes for failing tests, of correct code.
The first concerns the semantics of the END block. The code looked roughly like
Now what I actually wanted here was
The result of this is that rendered as strings of bytes, the two addresses don't necessarily contain all the same bytes as each other, even though they represent the same address. The way to fix this one is to unpack the addresses, known to be AF_INET addresses, and use is_deeply instead:
The first concerns the semantics of the END block. The code looked roughly like
use Test::MoreThe idea of this code was to ensure that socat is no longer running when the test exits. Of course, if the socat program isn't installed, the entire test is skipped. And the END block is still run. The result of this is that since $kid is undefined, the containing perl process is sent SIGTERM instead, and the test harness exits with an error. Ooops.
system( 'socat -help' ) == 0 or plan skip_all => "No socat";
plan tests => 3;
open my $kid, "-|", "socat", .... or die;
END { kill TERM => $kid }
Now what I actually wanted here was
END { kill TERM => $kid if defined $kid }I wonder if this situation would warrant a new block-alike, perhaps lets call it ENDX, which is only executed at END time if the line declaring it was actually reached in code. Perhaps it can be hacked up bymy @ends;The second failure is a curious one that starts off looking like an OS-specific bug in the code. All the Linux smoke boxes were giving fails on a particularly innocent-looking test
sub ENDX(&) {
push @ends, $_[0];
}
END { $_->() for @ends }
...
ENDX { kill TERM => $kid };
is( $client->peeraddr, $server->sockaddr, 'Client socket address' );Under closer inspection, it seems that the way Linux returns socket addresses from the kernel doesn't initialise the "holes" in the address structure, whereas most other OSes do.
The result of this is that rendered as strings of bytes, the two addresses don't necessarily contain all the same bytes as each other, even though they represent the same address. The way to fix this one is to unpack the addresses, known to be AF_INET addresses, and use is_deeply instead:
use Socket qw( unpack_sockaddr_in );This doesn't look too neat this way, but perhaps there's some scope for considering a Test::Sockaddr module or somesuch, to neaten it up. Perhaps a little special-purpose though..
is_deeply( [ unpack_sockaddr_in $client->peeraddr ],
[ unpack_sockaddr_in $server->sockaddr ],
'Client socket address' );
Subscribe to:
Posts (Atom)