[dev] Database access in process fork

Ian Roth iron_hat at hotmail.com
Fri Aug 17 00:27:05 UTC 2012


I have a cron script that takes requests from a queue and makes calls to cloud service based on those queued requests. These API calls can take a long time to receive a response, and under heavy load it would be nice to be able to use one process per request. The trouble I am having is that using pcntl_fork() causes child processes to use the same Horde_Db instance as the parent, and this causes exceptions when multiple child processes attempt to write a response back to the database. What is the best approach: creating a new Horde_Db instance in each child process, or using semaphore between child processes to avoid resource deadlock? Here is the code I have so far, and it can be modified at this url: https://gist.github.com/3154317

#!/usr/bin/env php
<?php

$baseFile = __DIR__ . '/../lib/Application.php';
if (file_exists($baseFile)) {
    require_once $baseFile;
}
Horde_Registry::appInit(<app>, array('authentication' => false, 'cli' => true));

$driver = $GLOBALS['injector']->getInstance('<app>_Factory_Driver')->create();
$processes = $driver->getProcessestoStart();

foreach($processes as $process) {
    $pid = pcntl_fork();
    if ($pid == -1) { // Error in forking
        throw new <app>_Exception('Unable to fork.');
    } elseif ($pid) { // Parent process

    } else { // End process
        start_process($process);
        exit;
    }
}

function start_process($process) {
    $driver = $GLOBALS['injector']->getInstance('<app>_Factory_Driver')->create();

    require_once 'AWSSDKforPHP/sdk.class.php';
    $ec2 = new AmazonEC2(array('key' => $GLOBALS['conf']['aws']['key'], 'secret' => $GLOBALS['conf']['aws']['secretkey']));

    $response = $ec2->create_key_pair($process['key_name']);
    $driver->addClusterLog($process['cluster_id'], $response);


Regards,
Ian 		 	   		  


More information about the dev mailing list