[dev] Database access in process fork (Jan Schneider)

Jan Schneider jan at horde.org
Thu Aug 30 09:18:31 UTC 2012


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

>> 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.
>
> I think I will treat this problem as time constrained. How do I  
> force the driver factory to give a new instance each time it is  
> requested? I based the code after the SQL driver code found in the  
> skeleton application.

Use createDb(), not create() of the factory.

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


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



More information about the dev mailing list