Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 102 lines (81 sloc) 2.455 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
<?php defined('SYSPATH') or die('No direct script access.');

abstract class Controller_Farmable extends Controller {

/**
* number of items $_POST[$this->get_key()] should be distributed for
* @var int
*/
protected $_workable_limit = 2;

/**
* Number of workers to distribute this request via
* @var int
*/
protected $_worker_count = 3;

/**
* Name of key within which data is held
* @var string
*/
protected $_key_name = 'data';

/**
* worker responses
* Responses received from ants
* @var Array
*/
protected $_responses = array();

/**
* Divides the passed workload and handles the division of workload between
* multiple instances
*/
public function before()
{
// If original request and above the workable limit then we
// look to parallelise the work

$m_target = $this->request->post($this->_key_name);

if
(
$this->request->is_initial()
AND isset($m_target)
AND is_array($m_target)
AND count($m_target) >= $this->_workable_limit
)
{
// Instantiate gearman client
$obj_gearman = new GearmanClient;
$obj_gearman->addServer();

// Divide the work into $this->_worker_count chunks for processing
$int_chunk_size = round( count($m_target) / $this->_worker_count );

$arr_chunks = array_chunk( $m_target, $int_chunk_size );

// Reverse the route..
$str_route = $this->request->uri();

// Update the controller action to our own nullifier
$this->request->action('nullifier');

// Schedule each of the requests
$c = 0;
foreach ($arr_chunks as $chunk) {

// Format the string to be passed to the worker by formatting the post
$arr_d = $_POST;
$arr_d[$this->_key_name] = $arr_chunks[$c];

$str_data = $str_route . "#" . http_build_query($arr_d);

$obj_gearman->addTask('make_request', $str_data);
$c++;
}

// Set the complete requests callback
$obj_gearman->setCompleteCallback(array($this,"complete"));

// Execute the requests
$obj_gearman->runTasks();
}
}

final public function action_nullifier()
{
// Decode the responses so as to merge
$arr_decoded = array();
foreach ($this->_worker_responses as $str_resp) {
$arr_decoded[] = json_decode($str_resp,1);
}

// Combine the responses and return!
return $this->response->body(json_encode(call_user_func_array("arr::merge", $arr_decoded)));
}

final public function complete($task)
{
$this->_worker_responses[] = $task->data();
}
}
Something went wrong with that request. Please try again.