Telephone +44(0)1524 64544
Email: info@shadowcat.co.uk

mstpan 8 - Async

Wed Dec 10 18:00:00 2014

mstpan 8 - Async

Now have problems two you

Don't

Really. The easiest way to deal with async is to avoid needing to do async. For a server, often preforking is quite sufficient even if you're I/O bound, since OS context switches aren't that slow. For batch process type things, multiple workers tends to be pretty effective.

A key thing to remember here is that even if you do absolutely need async, life can often be rendered simpler by isolating the async parts in its own process, and doing everything else synchronously.

threads.pm

This is the win32 fork emulation code exposed to perl space. Using it for threading works about as well as you might expect.

Shared variables are hilariously horrible, thread spawns make cold JVM startup times look good, and you still have all the problems inherent in threading as well.

The majority of the community has been very conscious of this for quite some time, and Rocco Caputo got a patch into 5.20 pointing out that it's officially discouraged (why did none of us think to do that sooner? I have no idea, I'm just glad somebody eventually had the sense to).

So, yeah, just don't. If you really want the API style, look at forks.pm which recreates the interface but using processes, and in fact often performs better than threads.pm.

POE

Originally intended to be an object remoting system, POE evolved into a very solid generic async system with a kinda weird API. It's been around for a long time, it's rock solid, and there's a huge ecosystem, but it seems to be relatively tricky for people to get their heads around when they first encounter it (even more so than async in general).

If you have code already using it, don't be afraid. You can always write newer parts with IO::Async if you like that better, since the two systems co-operate fine, and the maintainers consider that important to preserve.

MooseX::POE

A wrapper around the POE session system that lets you write them as Moose objects. Very nice for adding to an existing POE setup and avoiding a lot of the details, without making the system overly diverse in terms of the logic involved.

Reflex

A full Moose-based async system built by the author of POE, that runs atop POE. Lots of interesting ideas, but a bit too much runtime meta cleverness for my personal tastes. I'd strongly recommend this as something to steal structural ideas from, but would be reticent to use it directly.

AnyEvent

Originally intended to be the DBI of async, it sadly suffered massive mission creep and is now a sort-of-an-async-framework except with much lower level tools, which tends to leave it in a worst-of-both-worlds situation (e.g. the CondVar system is basically Future but without any of the useful features).

It has a huge ecosystem, and it will quite possibly be rational to use it, but it tends to be relatively inelegant and you'll likely find yourself building half a framework of your own on top of it.

For added bonus fun, the maintainer refuses to collaborate with the authors of other systems, preferring instead to add hard-coded die() statements to stop you using modules he doesn't like.

This is basically the same person/problem as JSON::XS except that there's no fork. Oh well.

IO::Async

IO::Async + Future is, frankly, the first async system that I don't find horrifically unpleasant to debug. Ok, it's still a trifle confusing, because async, but still.

It's a solid system, with a moderate sized and slowly increasing ecosystem, and does its best to play nice with everything else (the author has been known to play jenga with event systems to see how many he can have running atop each other :).

At this point I reach for IO::Async by default unless I've already got a large POE codebase, in which case I'm likely to use MooseX::POE.

Mojo::IOLoop

If you're using Mojolicious, you're already using this, so please just keep doing so. It's of the same level of quality and modernity as IO::Async, and its delay system is really neat - I personally prefer Futures, but that's very much an opinion rather than there being a clear 'better' involved.

Promises

An implementation of (mostly) the Promises/A spec that runs on top of pretty much all the available event loops - although if you're planning on doing hybrid blocking code, so does Future.

It's a neat piece of kit but I find Future's sequencing methods and the stuff in Future::Util to offer me more flexibility, so I stick to Future even when running atop something other than IO::Async.

Definitely worth a look, nonetheless.

curry

A small module I wrote as a helper for turning object methods into callbacks.

Completely agnostic of everything, it just constructs coderefs for you, with optional weakening.

Well worth a look to see if it'll be helpful, no matter what you're using.

Coda

Next, we move over into deployment land and I get to talk about libraries.

-- mst, out.