Fork me on GitHub

Kris Wallsmith

Symfony Guru at opensky.com.
Discussing web development, Symfony and fatherhood.

Posts tagged OpenSky

Apr 10

Hello Spork! (aka “Forking PHP…”)

A few months ago I was tasked with speeding up the upload of assets to the OpenSky CDN, which was taking a few minutes each deploy. I ended up dividing the upload into multiple processes using pcntl_fork() and bringing the total time of the upload down to a matter of seconds.

Since then I’ve been working on wrapping some of the complexities of working with a parent and child processes into an OO library and am happy to announce this experimental library: Spork.

Its usage is pretty straight forward.

<?php

use Spork\ProcessManager;
use Spork\Deferred\DeferredFactory;

$pm = new ProcessManager(new DeferredFactory());
$pm->fork(function() {
    // do something in a child process...
    echo posix_getpid();
})->then(function($output) {
    // do something in the parent process...
    printf('Parent %d forked child %d!', posix_getpid(), $output);
});

You can pass any callable into the process manager’s fork() method. In return you get a nice little deferred object which you can use to queue more callables to run after the child process exits. Just like the jQuery object I ♥ so much, there are three basic methods: always(), done(), and fail(), each of which accept a callable as an argument. There is also a then() method, which is a convenience method for adding a done and a fail callback in one method call.

Case Studies

If you end up using Spork I would like to hear about it. Please post your own blog and I’ll link to it, or send me a little description of what you’re doing and I’ll post it here.


Feb 21

Faster PHPUnit

I made a simple optimization to the test suite at OpenSky over the weekend and we are reaping big benefits. The premise is pretty straight forward. We use the setUp() method to create a lot of mock objects through our test suite. If these are allowed to accumulate they end up wasting a lot of space and slowing down your suite.

Luckily there is also a tearDown() method you can use to cleanup, and you can do it automatically if you use this base class:

<?php

abstract class BaseTestCase extends PHPUnit_Framework_TestCase
{
    protected function tearDown()
    {
        $refl = new ReflectionObject($this);
        foreach ($refl->getProperties() as $prop) {
            if (!$prop->isStatic() && 0 !== strpos($prop->getDeclaringClass()->getName(), 'PHPUnit_')) {
                $prop->setAccessible(true);
                $prop->setValue($this, null);
            }
        }
    }
}

Our buddy Jenkins is much happier now — builds are approximately 20% faster.


Oct 18