xing-gearman-ruby 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ ?>