xing-gearman-ruby 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,85 @@
1
+ <?php
2
+
3
+ /**
4
+ * Interface for Danga's Gearman job scheduling system
5
+ *
6
+ * PHP version 5.1.0+
7
+ *
8
+ * LICENSE: This source file is subject to the New BSD license that is
9
+ * available through the world-wide-web at the following URI:
10
+ * http://www.opensource.org/licenses/bsd-license.php. If you did not receive
11
+ * a copy of the New BSD License and are unable to obtain it through the web,
12
+ * please send a note to license@php.net so we can mail you a copy immediately.
13
+ *
14
+ * @category Net
15
+ * @package Net_Gearman
16
+ * @author Joe Stump <joe@joestump.net>
17
+ * @copyright 2007-2008 Digg.com, Inc.
18
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
19
+ * @version CVS: $Id$
20
+ * @link http://pear.php.net/package/Net_Gearman
21
+ * @link http://www.danga.com/gearman/
22
+ */
23
+
24
+ require_once 'Net/Gearman/Job/Common.php';
25
+ require_once 'Net/Gearman/Exception.php';
26
+
27
+ // Define this if you want your Jobs to be stored in a different
28
+ // path than the default.
29
+ if (!defined('NET_GEARMAN_JOB_PATH')) {
30
+ define('NET_GEARMAN_JOB_PATH', 'Net/Gearman/Job');
31
+ }
32
+
33
+ // Define this if you want your Jobs to have a prefix requirement
34
+ if (!defined('NET_GEARMAN_JOB_CLASS_PREFIX')) {
35
+ define('NET_GEARMAN_JOB_CLASS_PREFIX', 'Net_Gearman_Job_');
36
+ }
37
+
38
+ /**
39
+ * Job creation class
40
+ *
41
+ * @category Net
42
+ * @package Net_Gearman
43
+ * @author Joe Stump <joe@joestump.net>
44
+ * @copyright 2007-2008 Digg.com, Inc.
45
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
46
+ * @link http://www.danga.com/gearman/
47
+ * @see Net_Gearman_Job_Common, Net_Gearman_Worker
48
+ */
49
+ abstract class Net_Gearman_Job
50
+ {
51
+ /**
52
+ * Create an instance of a job
53
+ *
54
+ * The Net_Geraman_Worker class creates connections to multiple job servers
55
+ * and then fires off jobs using this function. It hands off the connection
56
+ * which made the request for the job so that the job can communicate its
57
+ * status from there on out.
58
+ *
59
+ * @param string $job Name of job (func in Gearman terms)
60
+ * @param object $conn Instance of Net_Gearman_Connection
61
+ * @param string $handle Gearman job handle of job
62
+ *
63
+ * @return object Instance of Net_Gearman_Job_Common child
64
+ * @see Net_Gearman_Job_Common
65
+ * @throws Net_Gearman_Exception
66
+ */
67
+ static public function factory($job, $conn, $handle)
68
+ {
69
+ $file = NET_GEARMAN_JOB_PATH . '/' . $job . '.php';
70
+ include_once $file;
71
+ $class = NET_GEARMAN_JOB_CLASS_PREFIX . $job;
72
+ if (!class_exists($class)) {
73
+ throw new Net_Gearman_Job_Exception('Invalid Job class');
74
+ }
75
+
76
+ $instance = new $class($conn, $handle);
77
+ if (!$instance instanceof Net_Gearman_Job_Common) {
78
+ throw new Net_Gearman_Job_Exception('Job is of invalid type');
79
+ }
80
+
81
+ return $instance;
82
+ }
83
+ }
84
+
85
+ ?>
@@ -0,0 +1,320 @@
1
+ <?php
2
+
3
+ /**
4
+ * Interface for Danga's Gearman job scheduling system
5
+ *
6
+ * PHP version 5.1.0+
7
+ *
8
+ * LICENSE: This source file is subject to the New BSD license that is
9
+ * available through the world-wide-web at the following URI:
10
+ * http://www.opensource.org/licenses/bsd-license.php. If you did not receive
11
+ * a copy of the New BSD License and are unable to obtain it through the web,
12
+ * please send a note to license@php.net so we can mail you a copy immediately.
13
+ *
14
+ * @category Net
15
+ * @package Net_Gearman
16
+ * @author Joe Stump <joe@joestump.net>
17
+ * @copyright 2007-2008 Digg.com, Inc.
18
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
19
+ * @version CVS: $Id$
20
+ * @link http://pear.php.net/package/Net_Gearman
21
+ * @link http://www.danga.com/gearman/
22
+ */
23
+
24
+ require_once 'Net/Gearman/Connection.php';
25
+
26
+ /**
27
+ * A client for managing Gearmand servers
28
+ *
29
+ * This class implements the administrative text protocol used by Gearman to do
30
+ * a number of administrative tasks such as collecting stats on workers, the
31
+ * queue, shutting down the server, version, etc.
32
+ *
33
+ * @category Net
34
+ * @package Net_Gearman
35
+ * @author Joe Stump <joe@joestump.net>
36
+ * @copyright 2007-2008 Digg.com, Inc.
37
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
38
+ * @link http://www.danga.com/gearman/
39
+ */
40
+ class Net_Gearman_Manager
41
+ {
42
+ /**
43
+ * Connection resource
44
+ *
45
+ * @var resource $conn Connection to Gearman server
46
+ * @see Net_Gearman_Manager::sendCommand()
47
+ * @see Net_Gearman_Manager::recvCommand()
48
+ */
49
+ protected $conn = null;
50
+
51
+ /**
52
+ * The server is shutdown
53
+ *
54
+ * We obviously can't send more commands to a server after it's been shut
55
+ * down. This is set to true in Net_Gearman_Manager::shutdown() and then
56
+ * checked in Net_Gearman_Manager::sendCommand().
57
+ *
58
+ * @var boolean $shutdown
59
+ */
60
+ protected $shutdown = false;
61
+
62
+ /**
63
+ * Constructor
64
+ *
65
+ * @param string $server Host and port (e.g. 'localhost:7003')
66
+ * @param integer $timeout Connection timeout
67
+ *
68
+ * @throws Net_Gearman_Exception
69
+ * @see Net_Gearman_Manager::$conn
70
+ */
71
+ public function __construct($server, $timeout = 5)
72
+ {
73
+ if (strpos($server, ':')) {
74
+ list($host, $port) = explode(':', $server);
75
+ } else {
76
+ $host = $server;
77
+ $port = 7003;
78
+ }
79
+
80
+ $errCode = 0;
81
+ $errMsg = '';
82
+ $this->conn = @fsockopen($host, $port, $errCode, $errMsg, $timeout);
83
+ if ($this->conn === false) {
84
+ throw new Net_Gearman_Exception(
85
+ 'Could not connect to ' . $host . ':' . $port
86
+ );
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Get the version of Gearman running
92
+ *
93
+ * @return string
94
+ * @see Net_Gearman_Manager::sendCommand()
95
+ * @see Net_Gearman_Manager::checkForError()
96
+ */
97
+ public function version()
98
+ {
99
+ $this->sendCommand('version');
100
+ $res = fgets($this->conn, 4096);
101
+ $this->checkForError($res);
102
+ return trim($res);
103
+ }
104
+
105
+ /**
106
+ * Shut down Gearman
107
+ *
108
+ * @param boolean $graceful Whether it should be a graceful shutdown
109
+ *
110
+ * @return boolean
111
+ * @see Net_Gearman_Manager::sendCommand()
112
+ * @see Net_Gearman_Manager::checkForError()
113
+ * @see Net_Gearman_Manager::$shutdown
114
+ */
115
+ public function shutdown($graceful = false)
116
+ {
117
+ $cmd = ($graceful) ? 'shutdown graceful' : 'shutdown';
118
+ $this->sendCommand($cmd);
119
+ $res = fgets($this->conn, 4096);
120
+ $this->checkForError($res);
121
+
122
+ $this->shutdown = (trim($res) == 'OK');
123
+ return $this->shutdown;
124
+ }
125
+
126
+ /**
127
+ * Get worker status and info
128
+ *
129
+ * Returns the file descriptor, IP address, client ID and the abilities
130
+ * that the worker has announced.
131
+ *
132
+ * @return array A list of workers connected to the server
133
+ * @throws Net_Gearman_Exception
134
+ */
135
+ public function workers()
136
+ {
137
+ $this->sendCommand('workers');
138
+ $res = $this->recvCommand();
139
+ $workers = array();
140
+ $tmp = explode("\n", $res);
141
+ foreach ($tmp as $t) {
142
+ if (!Net_Gearman_Connection::stringLength($t)) {
143
+ continue;
144
+ }
145
+
146
+ list($info, $abilities) = explode(" : ", $t);
147
+ list($fd, $ip, $id) = explode(' ', $info);
148
+
149
+ $abilities = trim($abilities);
150
+
151
+ $workers[] = array(
152
+ 'fd' => $fd,
153
+ 'ip' => $ip,
154
+ 'id' => $id,
155
+ 'abilities' => empty($abilities) ? array() : explode(' ', $abilities)
156
+ );
157
+ }
158
+
159
+ return $workers;
160
+ }
161
+
162
+ /**
163
+ * Set maximum queue size for a function
164
+ *
165
+ * For a given function of job, the maximum queue size is adjusted to be
166
+ * max_queue_size jobs long. A negative value indicates unlimited queue
167
+ * size.
168
+ *
169
+ * If the max_queue_size value is not supplied then it is unset (and the
170
+ * default maximum queue size will apply to this function).
171
+ *
172
+ * @param string $function Name of function to set queue size for
173
+ * @param integer $size New size of queue
174
+ *
175
+ * @return boolean
176
+ * @throws Net_Gearman_Exception
177
+ */
178
+ public function setMaxQueueSize($function, $size)
179
+ {
180
+ if (!is_numeric($size)) {
181
+ throw new Net_Gearman_Exception('Queue size must be numeric');
182
+ }
183
+
184
+ if (preg_match('/[^a-z0-9_]/i', $function)) {
185
+ throw new Net_Gearman_Exception('Invalid function name');
186
+ }
187
+
188
+ $this->sendCommand('maxqueue ' . $function . ' ' . $size);
189
+ $res = fgets($this->conn, 4096);
190
+ $this->checkForError($res);
191
+ return (trim($res) == 'OK');
192
+ }
193
+
194
+ /**
195
+ * Get queue/worker status by function
196
+ *
197
+ * This function queries for queue status. The array returned is keyed by
198
+ * the function (job) name and has how many jobs are in the queue, how
199
+ * many jobs are running and how many workers are capable of performing
200
+ * that job.
201
+ *
202
+ * @return array An array keyed by function name
203
+ * @throws Net_Gearman_Exception
204
+ */
205
+ public function status()
206
+ {
207
+ $this->sendCommand('status');
208
+ $res = $this->recvCommand();
209
+
210
+ $status = array();
211
+ $tmp = explode("\n", $res);
212
+ foreach ($tmp as $t) {
213
+ if (!Net_Gearman_Connection::stringLength($t)) {
214
+ continue;
215
+ }
216
+
217
+ list($func, $inQueue, $jobsRunning, $capable) = explode("\t", $t);
218
+
219
+ $status[$func] = array(
220
+ 'in_queue' => $inQueue,
221
+ 'jobs_running' => $jobsRunning,
222
+ 'capable_workers' => $capable
223
+ );
224
+ }
225
+
226
+ return $status;
227
+ }
228
+
229
+ /**
230
+ * Send a command
231
+ *
232
+ * @param string $cmd The command to send
233
+ *
234
+ * @return void
235
+ * @throws Net_Gearman_Exception
236
+ */
237
+ protected function sendCommand($cmd)
238
+ {
239
+ if ($this->shutdown) {
240
+ throw new Net_Gearman_Exception('This server has been shut down');
241
+ }
242
+
243
+ fwrite($this->conn,
244
+ $cmd . "\r\n",
245
+ Net_Gearman_Connection::stringLength($cmd . "\r\n"));
246
+ }
247
+
248
+ /**
249
+ * Receive a response
250
+ *
251
+ * For most commands Gearman returns a bunch of lines and ends the
252
+ * transmission of data with a single line of ".\n". This command reads
253
+ * in everything until ".\n". If the command being sent is NOT ended with
254
+ * ".\n" DO NOT use this command.
255
+ *
256
+ * @throws Net_Gearman_Exception
257
+ * @return string
258
+ */
259
+ protected function recvCommand()
260
+ {
261
+ $ret = '';
262
+ while (true) {
263
+ $data = fgets($this->conn, 4096);
264
+ $this->checkForError($data);
265
+ if ($data == ".\n") {
266
+ break;
267
+ }
268
+
269
+ $ret .= $data;
270
+ }
271
+
272
+ return $ret;
273
+ }
274
+
275
+ /**
276
+ * Check for an error
277
+ *
278
+ * Gearman returns errors in the format of 'ERR code_here Message+here'.
279
+ * This method checks returned values from the server for this error format
280
+ * and will throw the appropriate exception.
281
+ *
282
+ * @param string $data The returned data to check for an error
283
+ *
284
+ * @return void
285
+ * @throws Net_Gearman_Exception
286
+ */
287
+ protected function checkForError($data)
288
+ {
289
+ $data = trim($data);
290
+ if (preg_match('/^ERR/', $data)) {
291
+ list(, $code, $msg) = explode(' ', $data);
292
+ throw new Net_Gearman_Exception($msg, urldecode($code));
293
+ }
294
+ }
295
+
296
+ /**
297
+ * Disconnect from server
298
+ *
299
+ * @return void
300
+ * @see Net_Gearman_Manager::$conn
301
+ */
302
+ public function disconnect()
303
+ {
304
+ if (is_resource($this->conn)) {
305
+ fclose($this->conn);
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Destructor
311
+ *
312
+ * @return void
313
+ */
314
+ public function __destruct()
315
+ {
316
+ $this->disconnect();
317
+ }
318
+ }
319
+
320
+ ?>
@@ -0,0 +1,215 @@
1
+ <?php
2
+
3
+ /**
4
+ * Interface for Danga's Gearman job scheduling system
5
+ *
6
+ * PHP version 5.1.0+
7
+ *
8
+ * LICENSE: This source file is subject to the New BSD license that is
9
+ * available through the world-wide-web at the following URI:
10
+ * http://www.opensource.org/licenses/bsd-license.php. If you did not receive
11
+ * a copy of the New BSD License and are unable to obtain it through the web,
12
+ * please send a note to license@php.net so we can mail you a copy immediately.
13
+ *
14
+ * @category Net
15
+ * @package Net_Gearman
16
+ * @author Joe Stump <joe@joestump.net>
17
+ * @copyright 2007-2008 Digg.com, Inc.
18
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
19
+ * @version CVS: $Id$
20
+ * @link http://pear.php.net/package/Net_Gearman
21
+ * @link http://www.danga.com/gearman/
22
+ */
23
+
24
+ require_once 'Net/Gearman/Task.php';
25
+
26
+ /**
27
+ * A class for creating sets of tasks
28
+ *
29
+ * <code>
30
+ * <?php
31
+ * require_once 'Net/Gearman/Client.php';
32
+ *
33
+ * // This is the callback function for our tasks
34
+ * function echoResult($result) {
35
+ * echo 'The result was: ' . $result . "\n";
36
+ * }
37
+ *
38
+ * // Job name is the key, arguments to job are in the value array
39
+ * $jobs = array(
40
+ * 'AddTwoNumbers' => array('1', '2'),
41
+ * 'Multiply' => array('3', '4')
42
+ * );
43
+ *
44
+ * $set = new Net_Gearman_Set();
45
+ * foreach ($jobs as $job => $args) {
46
+ * $task = new Net_Gearman_Task($job, $args);
47
+ * $task->attachCallback('echoResult');
48
+ * $set->addTask($task);
49
+ * }
50
+ *
51
+ * $client = new Net_Gearman_Client(array(
52
+ * '127.0.0.1:7003', '127.0.0.1:7004'
53
+ * ));
54
+ *
55
+ * $client->runSet($set);
56
+ *
57
+ * ?>
58
+ * </code>
59
+ *
60
+ * @category Net
61
+ * @package Net_Gearman
62
+ * @author Joe Stump <joe@joestump.net>
63
+ * @copyright 2007-2008 Digg.com, Inc.
64
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
65
+ * @link http://www.danga.com/gearman/
66
+ * @see Net_Gearman_Job_Common, Net_Gearman_Worker
67
+ */
68
+ class Net_Gearman_Set implements IteratorAggregate, Countable
69
+ {
70
+ /**
71
+ * Tasks count
72
+ *
73
+ * @var integer $tasksCount
74
+ */
75
+ public $tasksCount = 0;
76
+
77
+ /**
78
+ * Tasks to run
79
+ *
80
+ * @var array $tasks
81
+ */
82
+ public $tasks = array();
83
+
84
+ /**
85
+ * Handle to task mapping
86
+ *
87
+ * @var array $handles
88
+ */
89
+ public $handles = array();
90
+
91
+ /**
92
+ * Callback registered for set
93
+ *
94
+ * @var mixed $callback
95
+ */
96
+ protected $callback = null;
97
+
98
+ /**
99
+ * Constructor
100
+ *
101
+ * @param array $tasks Array of tasks to run
102
+ *
103
+ * @return void
104
+ * @see Net_Gearman_Task
105
+ */
106
+ public function __construct(array $tasks = array())
107
+ {
108
+ foreach ($tasks as $task) {
109
+ $this->addTask($task);
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Add a task to the set
115
+ *
116
+ * @param object $task Task to add to the set
117
+ *
118
+ * @return void
119
+ * @see Net_Gearman_Task, Net_Gearman_Set::$tasks
120
+ */
121
+ public function addTask(Net_Gearman_Task $task)
122
+ {
123
+ if (!isset($this->tasks[$task->uniq])) {
124
+ $this->tasks[$task->uniq] = $task;
125
+ $this->tasksCount++;
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Get a task
131
+ *
132
+ * @param string $handle Handle of task to get
133
+ *
134
+ * @return object Instance of task
135
+ * @throws Net_Gearman_Exception
136
+ */
137
+ public function getTask($handle)
138
+ {
139
+ if (!isset($this->handles[$handle])) {
140
+ throw new Net_Gearman_Exception('Unknown handle');
141
+ }
142
+
143
+ if (!isset($this->tasks[$this->handles[$handle]])) {
144
+ throw new Net_Gearman_Exception('No task by that handle');
145
+ }
146
+
147
+ return $this->tasks[$this->handles[$handle]];
148
+ }
149
+
150
+ /**
151
+ * Is this set finished running?
152
+ *
153
+ * This function will return true if all of the tasks in the set have
154
+ * finished running. If they have we also run the set callbacks if there
155
+ * is one.
156
+ *
157
+ * @return boolean
158
+ */
159
+ public function finished()
160
+ {
161
+ if ($this->tasksCount == 0) {
162
+ if (isset($this->callback)) {
163
+ foreach ($this->tasks as $task) {
164
+ $results[] = $task->result;
165
+ }
166
+
167
+ call_user_func($this->callback, $results);
168
+ }
169
+
170
+ return true;
171
+ }
172
+
173
+ return false;
174
+ }
175
+
176
+ /**
177
+ * Attach a callback to this set
178
+ *
179
+ * @param callback $callback A valid PHP callback
180
+ *
181
+ * @return void
182
+ * @throws Net_Gearman_Exception
183
+ */
184
+ public function attachCallback($callback)
185
+ {
186
+ if (!is_callable($callback)) {
187
+ throw new Net_Gearman_Exception('Invalid callback specified');
188
+ }
189
+
190
+ $this->callback = $callback;
191
+ }
192
+
193
+ /**
194
+ * Get the iterator
195
+ *
196
+ * @return ArrayIterator Tasks
197
+ */
198
+ public function getIterator()
199
+ {
200
+ return new ArrayIterator($this->tasks);
201
+ }
202
+
203
+ /**
204
+ * Get the task count
205
+ *
206
+ * @return int Number of tasks in the set
207
+ * @see {@link Countable::count()}
208
+ */
209
+ public function count()
210
+ {
211
+ return $this->tasksCount;
212
+ }
213
+ }
214
+
215
+ ?>