[dev] Database access in process fork

Jan Schneider jan at horde.org
Fri Aug 17 16:43:11 UTC 2012


Zitat von Ian Roth <iron_hat at hotmail.com>:

> 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

You could either use a separate Horde_Db instance for each process or  
use some locking mechanism to avoid concurrent access. The choice  
probably depends on whether you need to scale this application with  
time constraints or resource constraints.

> #!/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


-- 
Jan Schneider
The Horde Project
http://www.horde.org/



More information about the dev mailing list