Padre::Task 3.0 - Smaller and safer with full service support

Padre 0.90 is a very important release in the maturity of the Padre IDE, as it represents the closest to what you might call a Beta that we've produced.

And it's certainly the best and most stable release since late 2010. But looking forward to 1.0 there's one glaring project-level issue left.

Once we do a "stable" release, we should finally be aiming to achieve fairly decent back-compatibility. And Padre has definitely tossed aside back-compat in exchange for faster development at every opportunity so far.

So if we're going to do a 1.0 release, we probably should take one final pass over the major APIs and break them horribly so that we have APIs that we're happy to support for a long time. And this is the major focus of the next 0.92 release.

One of the most important of these is Padre::Task, which is the API we use to run things in the background.

The new third-generation task API doesn't so much replace the second-generation one as rebuild it and complete it to the original concept.

The restoration of slave mastering provided the biggest memory win for 0.90, building a medium-weight threading model on otherwise painfully heavy threading model. It works by spawning one thread as early as possible after interpreter startup, and then having this slave master spawn all subsequent worker threads.

As a bonus, these subsequent threads are also spawned in the background and so they don't block the GUI. Which means we no longer need to pre-spawn any workers to avoid visible blocking, and we can just do all thread spawning on demand, which makes startup even faster.

On Windows, per-thread memory overhead comes down from 35meg to 16meg. In Task 3.0 we now do additional tuning of the thread stack allocation (which is overly generous) to bring the per-thread overheads further down to just 6meg. Cheaper threads means we can afford more of them, and so we can do more types of analysis or backups or indexing in parallel without significant memory cost.

It also opens up the idea of permanently running background "services" for continuous communication or monitoring, all without blocking the foreground.

To this end, Task 3.0 provides a new set of cross-platform functionality which allow background tasks to communicate with the foreground, and allow the foreground "owner" of a task to have more fine-grained awareness of the state of the task, and to communicate
back to the task in response to messages from it.

This has already allowed the experimental Swarm plugin (which enables collaborative development) to move it's communication stack into the background. It should also enable indexers and other analysis to occur incrementally without bothering the front-end, or for continuous integration or continuous execution of your test suite.

It may also mean we can implement concepts such as host services, for example a common POE background thread where many different lightweight IO-bound tasks can share a single background thread instead of needing one of their own.

It would also allow the creation of GUI applications with POE/AnyEvent embedded logic that doesn't require full integration of the runloops, and an entire CPU is available for the POE runloop separate to the CPU for the front-end.

Finally, Task 3.0 does some of the internals of threads more cleanly, join()ing instead of detach()ing, and shutting down background tasks much more correctly than we previously did.

The rewrite isn't quite done yet, but it's starting to look pretty damned sexy. The kind of thing that it might finally be worth spinning out as a standalone CPAN module to be included in any Wx applicaition.

Leave a comment

About Adam Kennedy

user-pic I blog about Perl.