/** * 001-echo_req.phpt * * @return void */ public function testSend() { $connection = Net_Gearman_Connection::connect(); Net_Gearman_Connection::send($connection, 'echo_req', array('text' => 'foobar')); do { $ret = Net_Gearman_Connection::read($connection); } while (is_array($ret) && !count($ret)); Net_Gearman_Connection::close($connection); $this->assertType('array', $ret); $this->assertEquals('echo_res', $ret['function']); $this->assertEquals(17, $ret['type']); $this->assertType('array', $ret['data']); $this->assertEquals('foobar', $ret['data']['text']); }
/** * Constructor * * @param array $servers An array of servers or a single server * @param integer $timeout Timeout in microseconds * * @return void * @throws Net_Gearman_Exception * @see Net_Gearman_Connection */ public function __construct($servers, $timeout = 1000) { if (!is_array($servers) && strlen($servers)) { $servers = array($servers); } elseif (is_array($servers) && !count($servers)) { throw new Net_Gearman_Exception('Invalid servers specified'); } $this->servers = $servers; foreach ($this->servers as $key => $server) { $conn = Net_Gearman_Connection::connect($server, $timeout); if (!Net_Gearman_Connection::isConnected($conn)) { unset($this->servers[$key]); continue; } $this->conn[] = $conn; } $this->timeout = $timeout; }
/** * Begin working * * This starts the worker on its journey of actually working. The first * argument is a PHP callback to a function that can be used to monitor * the worker. If no callback is provided then the worker works until it * is killed. The monitor is passed two arguments; whether or not the * worker is idle and when the last job was ran. * * @param callback $monitor Function to monitor work * * @return void * @see Net_Gearman_Connection::send(), Net_Gearman_Connection::connect() * @see Net_Gearman_Worker::doWork(), Net_Gearman_Worker::addAbility() */ public function beginWork($monitor = null) { if (!is_callable($monitor)) { $monitor = array($this, 'stopWork'); } $write = null; $except = null; $working = true; $lastJob = time(); $retryTime = 5; while ($working) { $sleep = true; $currentTime = time(); foreach ($this->conn as $server => $socket) { try { $worked = $this->doWork($socket); } catch (Net_Gearman_Exception $e) { unset($this->conn[$server]); $this->retryConn[$server] = $currentTime; } if ($worked) { $lastJob = time(); $sleep = false; } } $idle = false; if ($sleep && count($this->conn)) { foreach ($this->conn as $socket) { Net_Gearman_Connection::send($socket, 'pre_sleep'); } $read = $this->conn; socket_select($read, $write, $except, 60); $idle = count($read) == 0; } $retryChange = false; foreach ($this->retryConn as $s => $lastTry) { if ($lastTry + $retryTime < $currentTime) { try { $conn = Net_Gearman_Connection::connect($s); $this->conn[$s] = $conn; $retryChange = true; unset($this->retryConn[$s]); Net_Gearman_Connection::send($conn, "set_client_id", array("client_id" => $this->id)); } catch (Net_Gearman_Exception $e) { $this->retryConn[$s] = $currentTime; } } } if (count($this->conn) == 0) { // sleep to avoid wasted cpu cycles if no connections to block on using socket_select sleep(1); } if ($retryChange === true) { // broadcast all abilities to all servers foreach ($this->abilities as $ability => $timeout) { $this->addAbility($ability, $timeout); } } if (call_user_func($monitor, $idle, $lastJob) == true) { $working = false; } } }
/** * Get a connection to a Gearman server * * @param string $uniq The unique id of the job * * @return resource A connection to a Gearman server */ protected function getConnection($uniq = null) { $conn = null; $start = microtime(true); $elapsed = 0; $servers = $this->servers; while ($conn === null && $elapsed < $this->timeout && count($servers)) { if (count($servers) === 1) { $key = key($servers); } elseif ($uniq === null) { $key = array_rand($servers); } else { $key = ord(substr(md5($uniq), -1)) % count($servers); } $server = $servers[$key]; if (empty($this->conn[$server])) { $conn = null; $start = microtime(true); try { $conn = Net_Gearman_Connection::connect($server, $this->timeout); } catch (Net_Gearman_Exception $e) { $conn = null; } if (!Net_Gearman_Connection::isConnected($conn)) { $conn = null; unset($servers[$key]); // we need to rekey the array $servers = array_values($servers); } else { $this->conn[$server] = $conn; break; } } else { $conn = $this->conn[$server]; } $elapsed = microtime(true) - $start; } if (empty($conn)) { throw new Net_Gearman_Exception("Failed to connect to any Gearman servers. Attempted " . implode(",", $this->servers)); } return $conn; }
/** * Constructor * * @param array $servers An array of servers or a single server * @param integer $timeout Timeout in microseconds * * @return void * @throws Net_Gearman_Exception * @see Net_Gearman_Connection */ public function __construct($servers = null, $timeout = 1000) { if (is_null($servers)) { $servers = array("localhost"); } elseif (!is_array($servers) && strlen($servers)) { $servers = array($servers); } elseif (is_array($servers) && !count($servers)) { throw new Net_Gearman_Exception('Invalid servers specified'); } $this->servers = $servers; foreach ($this->servers as $key => $server) { $server = trim($server); if (empty($server)) { throw new Net_Gearman_Exception('Invalid servers specified'); } try { $conn = Net_Gearman_Connection::connect($server, $timeout); } catch (Net_Gearman_Exception $e) { unset($this->servers[$key]); continue; } if (!Net_Gearman_Connection::isConnected($conn)) { unset($this->servers[$key]); continue; } $this->conn[] = $conn; $this->serverConnections[(int) $conn] = $server; } if (empty($this->conn)) { throw new Net_Gearman_Exception("Couldn't connect to any available servers"); } $this->timeout = $timeout; }