"Inside every large program, there is a small program trying to get out." --Tony Hoare
Abstractions incur overhead, yep. Fortunately, POE's higher-level abstractions (wheels, components) are entirely optional. The low-level abstract event loop primitives are still there: select_read(), alarm(), sig(), etc. There's a smaller POE inside. It's already out, but it's been a bit neglected.
History has a bigger role to play than abstractions in the obstruction of change. A long-established, stable module like POE has reduced mobility because lots of people actually use it. A newbie module like Reflex can reinvent itself every few weeks, and nobody is going to mind. The depth of the abstraction stack has nothing to do with it. Although POE+Reflex's is shorter and (I hope) a bit more efficient as a result.
If anything, the depth of the abstraction stack allows more rapid change to occur. There's wiggle room in each level of abstraction, and if I'm allowed to consider modules to be abstractions, then delegating development (via CPAN, for example) accelerates change. But I digress on a technicality.
I think it's a mistake to talk about POE's "programming style" as if that's a particular thing. The Perl I'm using has a motto: There Is More Than One Way To Do It. That applies to using POE. For example, you may prefer condvars or promises to callbacks. POE can do that. And if you prefer to write classes that provide callbacks or can be used as promises, then POE can do that via Reflex.
Yeah, the flexibility comes at a cost, but, as you say, all things do. I think the benefits are worth it, but of course I'm always looking for a better cost/benefit ratio. All reasonable suggestions considered.
Well, that sucks. Maybe the default was different in my day.
I guess we'll have to leave it at this, since neither of us seems to be talking to someone who can do anything about it.
I've been making good progress on Reflex lately. I have to: I've applied to talk about it at YAPC::NA, so I need something to talk about! The code has been moving too fast for CPAN right now, but you can follow along at Reflex's repository on github. Here's a summary of the latest changes:
Check your CPAN contact address, which should be redirecting to your current e-mail address. rt.cpan.org is consistently contacting me via my @cpan.org address. Maybe I opted in for that? I don't recall... I set it up over a decade ago.
Also check https://rt.cpan.org/Prefs/Other.html to see whether your e-mail delivery is not "Suspended". If it is, I can only guess that it was auto-suspended because your @cpan.org address was bouncing.
If it's still not working: "Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com." That request is right there under the Search field on most (all?) rt.cpan.org pages.
Or not. Maybe someone from Best Practical will stumble across your blog and help out.
I can't answer your question directly, but I know that my Snerp Vortex is designed to support more than just git.
Someone with Mercurial chops could write SVN::Dump::Replayer::Mercural, and then snerp would support --replayer=mercurial
Sorry, no fancy graphs.
I wrote a deliberately simple program to count select_read() events per second. I ran it five times for each version of POE, averaged the results, and calculated the improvement using (new_rate/old_rate-1). Standard deviation for the sample sets were about 1%, if that matters.
#!/usr/bin/env perl
use warnings;
use strict;
use POE;
my $limit = 10_000;
my @start_times;
my @end_times;
my $count = 0;
my $filehandle;
POE::Session->create(
inline_states => {
_start => sub {
open $filehandle, "<", "/dev/zero" or die $!;
$_[KERNEL]->select_read($filehandle, "count");
@start_times = times();
},
count => sub {
if ($count < $limit) {
$count++;
return;
}
@end_times = times();
for (0..$#end_times) {
$end_times[$_] -= $start_times[$_];
}
$_[KERNEL]->select_read($filehandle, undef);
},
},
);
POE::Kernel->run();
print join("\t", "POE", "BENCH", "COUNT", "RATE"), "\n";
print join(
"\t",
$POE::VERSION,
"io/cpusec",
$limit,
sprintf("%.2f", $limit / ($end_times[0] + $end_times[1])),
), "\n";
I don't have a methodology to test the mark-and-sweep garbage collection in isolation. Got any ideas?
POE 1.280 has just been released, but it may take up to a day before your favorite CPAN mirror catches wind of it. You'll also need the latest POE::Test::Loops, version 1.030.
Those following along may notice that the version numbers jumped a little. That's because POE has undergone a couple optimizations that alter its behavior a little.
I/O Dispatch is Faster
Those of you who use POE for serious things should be aware of a couple changes introduced after 1.269.
Lately I've been hearing, repeatedly and loudly, that POE doesn't work with other event loops. I wrote the first bridge between POE and another event loop in May of 2000, so this is rather shocking news to me. I've had to rerun "make test" just to be sure I wasn't dreaming!
"Persistence" implies that data will be saved and loaded from disk, to a database, or some other persistent storage. That's not what the module does, so I think it needs a new name.
Lexical::Persistence objects are closures that make the values of lexical variables stick (or persist) in everything they call. In the following example, the Lexical::Persistence object makes sure that getter()'s version of $x contains the value stored by setter().
Distributed version control is great. It'll bring on the patches, establish world peace, and get you laid. It adds extra steps to your workflow, but they make everything easier. Don't ask me how. Even if I understood that trick, the Magician's Code wouldn't let me explain it to you.
POE::Test::Loops 1.020 will be released tonight. This is a suite of reusable tests for developers who want to add external event loop support to POE. Version 1.020 acquires more signal handler tests from POE. Existing POE::Loop authors should try the new tests at their earliest convenience. Those who need the code right away can track the repository: