Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions examples/02-decide-action.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

use \Parallel\Prefork;

require_once __DIR__ . '/../vendor/autoload.php';

main();
exit();

function main()
{
$start_time = time();
$prev_workers = 5;
$pp = new Prefork(array(
'max_workers' => 5,
'trap_signals' => array(
SIGHUP => SIGTERM,
SIGTERM => SIGTERM,
),
'decide_action' => function($current_worker, $max_worker) use($start_time, &$prev_workers) {
$current_time = time();
$max_worker = $max_worker + (int)(($current_time - $start_time) / 6);
if ( $max_worker > 10 ) {
$max_worker = 10;
}
if ( $max_worker !== $prev_workers ) {
echo "===> max worker: $prev_workers => $max_worker\n";
$prev_workers = $max_worker;
}
return $current_worker < $max_worker;
},
));
while ($pp->signalReceived() !== SIGTERM) {
loadConfig();
if ($pp->start()) {
continue;
}
workChildren();
$pp->finish();
}
$pp->waitAllChildren();
}

function loadConfig()
{
echo "Load configuration\n";
}

function workChildren()
{
for ($i = 1; $i <= 3; $i++) {
echo "Sleep $i seconds\n";
sleep($i);
}
}
35 changes: 27 additions & 8 deletions lib/Prefork.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ class Prefork
public $err_respawn_interval = 1;

/**
* @var callable lamda function that is called when a child is reaped
* @var callable lambda function that is called when a child is reaped
*/
public $on_child_reap = null;

/**
* callable lambda fuction that decide action
*/
private $decide_action = null;

private $signal_received = null;
private $manager_pid = null;
private $in_child = false;
Expand All @@ -43,6 +48,11 @@ function __construct(array $args = array())
? $args['max_workers'] : $this->max_workers;
$this->trap_signals = isset($args['trap_signals'])
? $args['trap_signals'] : $this->trap_signals;
$this->decide_action = isset($args['decide_action'])
? $args['decide_action'] : null;
if ( isset($this->decide_action) && !is_callable($this->decide_action) ){
die("decide_action should be callable\n");
}
Copy link
Owner

@travail travail Jan 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I wanted to say is:

  • Define setter for $decide_action. e.g. setDecideAction($function)
  • Validate $function above is_callable() in the setter.
  • No need to accept $args['decide_action'] in __construct() like above.
  • Set empty lambda function to $decide_action in __construct() to ensure $decide_action is callable.

Simple usage is like this.

$pp = new Prefork([
    ...,
]);
$pp->setDecideAction(function (...) use(...) { ... });


foreach (array_keys($this->trap_signals) as $sig) {
pcntl_signal($sig, array($this, '_signalHandler'), false);
Expand Down Expand Up @@ -75,7 +85,16 @@ public function start()
// main loop
while ($this->signal_received === null) {
$pid = null;
if (count(array_keys($this->worker_pids)) < $this->max_workers) {
$currect_workers = count(array_keys($this->worker_pids));
$should_fork = $currect_workers < $this->max_workers;
Copy link
Owner

@travail travail Jan 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to set default $decide_action in __construct().

// Set default $decide_action in __construct().
$this->decide_action = function($current_workers, $max_workers)) { return $current_workers < $max_workers; }

if ( is_callable($this->decide_action) ) {
try {
$should_fork = call_user_func_array($this->decide_action,array($currect_workers, $this->max_workers));
} catch ( \Exception $e ) {
printf("Exception. Use default action: %s\n",$e->getMessage());
}
}
if ($should_fork) {
$pid = pcntl_fork();
if ($pid === -1) {
echo "fork failed!\n";
Expand Down Expand Up @@ -164,16 +183,16 @@ private function generation()
return $this->generation;
}

// PHP 5.2.x don't have lamda function
private function _runChildReapCb($exit_pid, $status)
{
$cb = $this->on_child_reap;
if ($cb) {
/*
if (is_callable($cb)) {
try {
$cb->($exit_pid, $status);
}
*/
call_user_func_array($cb, array($exit_pid, $status));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validate $cb is callable if enable this method. $cb is null by default.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added validation on 7b94aee

} catch (\Exception $e) {
// ignore
printf("Ignore Exception: %s\n",$e->getMessage());
};
}
}
}