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.
- data/.gitignore +1 -0
- data/LICENSE +20 -0
- data/README +9 -0
- data/Rakefile +40 -0
- data/VERSION.yml +4 -0
- data/examples/Net/Gearman/Client.php +290 -0
- data/examples/Net/Gearman/Connection.php +410 -0
- data/examples/Net/Gearman/Exception.php +42 -0
- data/examples/Net/Gearman/Job/Common.php +135 -0
- data/examples/Net/Gearman/Job/Exception.php +45 -0
- data/examples/Net/Gearman/Job/Sleep.php +33 -0
- data/examples/Net/Gearman/Job.php +85 -0
- data/examples/Net/Gearman/Manager.php +320 -0
- data/examples/Net/Gearman/Set.php +215 -0
- data/examples/Net/Gearman/Task.php +300 -0
- data/examples/Net/Gearman/Worker.php +455 -0
- data/examples/client.php +23 -0
- data/examples/client.rb +15 -0
- data/examples/scale_image.rb +32 -0
- data/examples/scale_image_worker.rb +34 -0
- data/examples/server.rb +13 -0
- data/examples/worker.php +15 -0
- data/examples/worker.rb +23 -0
- data/gearman-ruby.gemspec +81 -0
- data/lib/gearman/client.rb +139 -0
- data/lib/gearman/server.rb +94 -0
- data/lib/gearman/task.rb +128 -0
- data/lib/gearman/taskset.rb +241 -0
- data/lib/gearman/testlib.rb +96 -0
- data/lib/gearman/util.rb +212 -0
- data/lib/gearman/worker.rb +341 -0
- data/lib/gearman.rb +76 -0
- data/test/client_test.rb +111 -0
- data/test/mock_client_test.rb +431 -0
- data/test/mock_worker_test.rb +213 -0
- data/test/worker_test.rb +61 -0
- metadata +98 -0
@@ -0,0 +1,455 @@
|
|
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
|
+
require_once 'Net/Gearman/Job.php';
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Gearman worker class
|
29
|
+
*
|
30
|
+
* Run an instance of a worker to listen for jobs. It then manages the running
|
31
|
+
* of jobs, etc.
|
32
|
+
*
|
33
|
+
* <code>
|
34
|
+
* <?php
|
35
|
+
*
|
36
|
+
* $servers = array(
|
37
|
+
* '127.0.0.1:7003',
|
38
|
+
* '127.0.0.1:7004'
|
39
|
+
* );
|
40
|
+
*
|
41
|
+
* $abilities = array('HelloWorld', 'Foo', 'Bar');
|
42
|
+
*
|
43
|
+
* try {
|
44
|
+
* $worker = new Net_Gearman_Worker($servers);
|
45
|
+
* foreach ($abilities as $ability) {
|
46
|
+
* $worker->addAbility('HelloWorld');
|
47
|
+
* }
|
48
|
+
* $worker->beginWork();
|
49
|
+
* } catch (Net_Gearman_Exception $e) {
|
50
|
+
* echo $e->getMessage() . "\n";
|
51
|
+
* exit;
|
52
|
+
* }
|
53
|
+
*
|
54
|
+
* ?>
|
55
|
+
* </code>
|
56
|
+
*
|
57
|
+
* @category Net
|
58
|
+
* @package Net_Gearman
|
59
|
+
* @author Joe Stump <joe@joestump.net>
|
60
|
+
* @copyright 2007-2008 Digg.com, Inc.
|
61
|
+
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
62
|
+
* @link http://www.danga.com/gearman/
|
63
|
+
* @see Net_Gearman_Job, Net_Gearman_Connection
|
64
|
+
*/
|
65
|
+
class Net_Gearman_Worker
|
66
|
+
{
|
67
|
+
/**
|
68
|
+
* Pool of connections to Gearman servers
|
69
|
+
*
|
70
|
+
* @var array $conn
|
71
|
+
*/
|
72
|
+
protected $conn = array();
|
73
|
+
|
74
|
+
/**
|
75
|
+
* Pool of retry connections
|
76
|
+
*
|
77
|
+
* @var array $conn
|
78
|
+
*/
|
79
|
+
protected $retryConn = array();
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Pool of worker abilities
|
83
|
+
*
|
84
|
+
* @var array $conn
|
85
|
+
*/
|
86
|
+
protected $abilities = array();
|
87
|
+
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Callbacks registered for this worker
|
91
|
+
*
|
92
|
+
* @var array $callback
|
93
|
+
* @see Net_Gearman_Worker::JOB_START
|
94
|
+
* @see Net_Gearman_Worker::JOB_COMPLETE
|
95
|
+
* @see Net_Gearman_Worker::JOB_FAIL
|
96
|
+
*/
|
97
|
+
protected $callback = array(
|
98
|
+
self::JOB_START => array(),
|
99
|
+
self::JOB_COMPLETE => array(),
|
100
|
+
self::JOB_FAIL => array()
|
101
|
+
);
|
102
|
+
|
103
|
+
/**
|
104
|
+
* Unique id for this worker
|
105
|
+
*
|
106
|
+
* @var string $id
|
107
|
+
*/
|
108
|
+
protected $id = "";
|
109
|
+
|
110
|
+
|
111
|
+
/**
|
112
|
+
* Callback types
|
113
|
+
*
|
114
|
+
* @const integer JOB_START Ran when a job is started
|
115
|
+
* @const integer JOB_COMPLETE Ran when a job is finished
|
116
|
+
* @const integer JOB_FAIL Ran when a job fails
|
117
|
+
*/
|
118
|
+
const JOB_START = 1;
|
119
|
+
const JOB_COMPLETE = 2;
|
120
|
+
const JOB_FAIL = 3;
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Constructor
|
124
|
+
*
|
125
|
+
* @param array $servers List of servers to connect to
|
126
|
+
* @param string $id Optional unique id for this worker
|
127
|
+
*
|
128
|
+
* @return void
|
129
|
+
* @throws Net_Gearman_Exception
|
130
|
+
* @see Net_Gearman_Connection
|
131
|
+
*/
|
132
|
+
public function __construct($servers, $id = "")
|
133
|
+
{
|
134
|
+
if (!is_array($servers) && strlen($servers)) {
|
135
|
+
$servers = array($servers);
|
136
|
+
} elseif (is_array($servers) && !count($servers)) {
|
137
|
+
throw new Net_Gearman_Exception('Invalid servers specified');
|
138
|
+
}
|
139
|
+
|
140
|
+
if(empty($id)){
|
141
|
+
$id = "pid_".getmypid()."_".uniqid();
|
142
|
+
}
|
143
|
+
|
144
|
+
$this->id = $id;
|
145
|
+
|
146
|
+
foreach ($servers as $s) {
|
147
|
+
try {
|
148
|
+
$conn = Net_Gearman_Connection::connect($s);
|
149
|
+
|
150
|
+
Net_Gearman_Connection::send($conn, "set_client_id", array("client_id" => $this->id));
|
151
|
+
|
152
|
+
$this->conn[$s] = $conn;
|
153
|
+
|
154
|
+
} catch (Net_Gearman_Exception $e) {
|
155
|
+
|
156
|
+
$this->retryConn[$s] = time();
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
if (empty($this->conn)) {
|
161
|
+
throw new Net_Gearman_Exception(
|
162
|
+
"Couldn't connect to any available servers"
|
163
|
+
);
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
/**
|
168
|
+
* Announce an ability to the job server
|
169
|
+
*
|
170
|
+
* @param string $ability Name of functcion/ability
|
171
|
+
* @param integer $timeout How long to give this job
|
172
|
+
*
|
173
|
+
* @return void
|
174
|
+
* @see Net_Gearman_Connection::send()
|
175
|
+
*/
|
176
|
+
public function addAbility($ability, $timeout = null)
|
177
|
+
{
|
178
|
+
$call = 'can_do';
|
179
|
+
$params = array('func' => $ability);
|
180
|
+
if (is_int($timeout) && $timeout > 0) {
|
181
|
+
$params['timeout'] = $timeout;
|
182
|
+
$call = 'can_do_timeout';
|
183
|
+
}
|
184
|
+
|
185
|
+
$this->abilities[$ability] = $timeout;
|
186
|
+
|
187
|
+
foreach ($this->conn as $conn) {
|
188
|
+
Net_Gearman_Connection::send($conn, $call, $params);
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
/**
|
193
|
+
* Begin working
|
194
|
+
*
|
195
|
+
* This starts the worker on its journey of actually working. The first
|
196
|
+
* argument is a PHP callback to a function that can be used to monitor
|
197
|
+
* the worker. If no callback is provided then the worker works until it
|
198
|
+
* is killed. The monitor is passed two arguments; whether or not the
|
199
|
+
* worker is idle and when the last job was ran.
|
200
|
+
*
|
201
|
+
* @param callback $monitor Function to monitor work
|
202
|
+
*
|
203
|
+
* @return void
|
204
|
+
* @see Net_Gearman_Connection::send(), Net_Gearman_Connection::connect()
|
205
|
+
* @see Net_Gearman_Worker::doWork(), Net_Gearman_Worker::addAbility()
|
206
|
+
*/
|
207
|
+
public function beginWork($monitor = null)
|
208
|
+
{
|
209
|
+
if (!is_callable($monitor)) {
|
210
|
+
$monitor = array($this, 'stopWork');
|
211
|
+
}
|
212
|
+
|
213
|
+
$write = null;
|
214
|
+
$except = null;
|
215
|
+
$working = true;
|
216
|
+
$lastJob = time();
|
217
|
+
$retryTime = 5;
|
218
|
+
|
219
|
+
while ($working) {
|
220
|
+
$sleep = true;
|
221
|
+
$currentTime = time();
|
222
|
+
|
223
|
+
foreach ($this->conn as $server => $socket) {
|
224
|
+
try {
|
225
|
+
$worked = $this->doWork($socket);
|
226
|
+
} catch (Net_Gearman_Exception $e) {
|
227
|
+
unset($this->conn[$server]);
|
228
|
+
$this->retryConn[$server] = $currentTime;
|
229
|
+
}
|
230
|
+
if ($worked) {
|
231
|
+
$lastJob = time();
|
232
|
+
$sleep = false;
|
233
|
+
}
|
234
|
+
}
|
235
|
+
|
236
|
+
$idle = false;
|
237
|
+
if ($sleep && count($this->conn)) {
|
238
|
+
foreach ($this->conn as $socket) {
|
239
|
+
Net_Gearman_Connection::send($socket, 'pre_sleep');
|
240
|
+
}
|
241
|
+
|
242
|
+
$read = $this->conn;
|
243
|
+
socket_select($read, $write, $except, 60);
|
244
|
+
$idle = (count($read) == 0);
|
245
|
+
}
|
246
|
+
|
247
|
+
$retryChange = false;
|
248
|
+
foreach ($this->retryConn as $s => $lastTry) {
|
249
|
+
if (($lastTry + $retryTime) < $currentTime) {
|
250
|
+
try {
|
251
|
+
$conn = Net_Gearman_Connection::connect($s);
|
252
|
+
$this->conn[$s] = $conn;
|
253
|
+
$retryChange = true;
|
254
|
+
unset($this->retryConn[$s]);
|
255
|
+
Net_Gearman_Connection::send($conn, "set_client_id", array("client_id" => $this->id));
|
256
|
+
} catch (Net_Gearman_Exception $e) {
|
257
|
+
$this->retryConn[$s] = $currentTime;
|
258
|
+
}
|
259
|
+
}
|
260
|
+
}
|
261
|
+
|
262
|
+
if (count($this->conn) == 0) {
|
263
|
+
// sleep to avoid wasted cpu cycles if no connections to block on using socket_select
|
264
|
+
sleep(1);
|
265
|
+
}
|
266
|
+
|
267
|
+
if ($retryChange === true) {
|
268
|
+
// broadcast all abilities to all servers
|
269
|
+
foreach ($this->abilities as $ability => $timeout) {
|
270
|
+
$this->addAbility($ability, $timeout);
|
271
|
+
}
|
272
|
+
}
|
273
|
+
|
274
|
+
if (call_user_func($monitor, $idle, $lastJob) == true) {
|
275
|
+
$working = false;
|
276
|
+
}
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
/**
|
281
|
+
* Listen on the socket for work
|
282
|
+
*
|
283
|
+
* Sends the 'grab_job' command and then listens for either the 'noop' or
|
284
|
+
* the 'no_job' command to come back. If the 'job_assign' comes down the
|
285
|
+
* pipe then we run that job.
|
286
|
+
*
|
287
|
+
* @param resource $socket The socket to work on
|
288
|
+
*
|
289
|
+
* @return boolean Returns true if work was done, false if not
|
290
|
+
* @throws Net_Gearman_Exception
|
291
|
+
* @see Net_Gearman_Connection::send()
|
292
|
+
*/
|
293
|
+
protected function doWork($socket)
|
294
|
+
{
|
295
|
+
Net_Gearman_Connection::send($socket, 'grab_job');
|
296
|
+
|
297
|
+
$resp = array('function' => 'noop');
|
298
|
+
while (count($resp) && $resp['function'] == 'noop') {
|
299
|
+
$resp = Net_Gearman_Connection::blockingRead($socket);
|
300
|
+
}
|
301
|
+
|
302
|
+
if (in_array($resp['function'], array('noop', 'no_job'))) {
|
303
|
+
return false;
|
304
|
+
}
|
305
|
+
|
306
|
+
if ($resp['function'] != 'job_assign') {
|
307
|
+
throw new Net_Gearman_Exception('Holy Cow! What are you doing?!');
|
308
|
+
}
|
309
|
+
|
310
|
+
$name = $resp['data']['func'];
|
311
|
+
$handle = $resp['data']['handle'];
|
312
|
+
$arg = array();
|
313
|
+
|
314
|
+
if (isset($resp['data']['arg']) &&
|
315
|
+
Net_Gearman_Connection::stringLength($resp['data']['arg'])) {
|
316
|
+
$arg = json_decode($resp['data']['arg'], true);
|
317
|
+
if($arg === null){
|
318
|
+
$arg = $resp['data']['arg'];
|
319
|
+
}
|
320
|
+
}
|
321
|
+
|
322
|
+
$job = Net_Gearman_Job::factory($name, $socket, $handle);
|
323
|
+
try {
|
324
|
+
$this->start($handle, $name, $arg);
|
325
|
+
$res = $job->run($arg);
|
326
|
+
if (!is_array($res)) {
|
327
|
+
$res = array('result' => $res);
|
328
|
+
}
|
329
|
+
|
330
|
+
$job->complete($res);
|
331
|
+
$this->complete($handle, $name, $res);
|
332
|
+
} catch (Net_Gearman_Job_Exception $e) {
|
333
|
+
$job->fail();
|
334
|
+
$this->fail($handle, $name, $e);
|
335
|
+
}
|
336
|
+
|
337
|
+
// Force the job's destructor to run
|
338
|
+
$job = null;
|
339
|
+
|
340
|
+
return true;
|
341
|
+
}
|
342
|
+
|
343
|
+
/**
|
344
|
+
* Attach a callback
|
345
|
+
*
|
346
|
+
* @param callback $callback A valid PHP callback
|
347
|
+
* @param integer $type Type of callback
|
348
|
+
*
|
349
|
+
* @return void
|
350
|
+
* @throws Net_Gearman_Exception
|
351
|
+
*/
|
352
|
+
public function attachCallback($callback, $type = self::JOB_COMPLETE)
|
353
|
+
{
|
354
|
+
if (!is_callable($callback)) {
|
355
|
+
throw new Net_Gearman_Exception('Invalid callback specified');
|
356
|
+
}
|
357
|
+
|
358
|
+
$this->callback[$type][] = $callback;
|
359
|
+
}
|
360
|
+
|
361
|
+
/**
|
362
|
+
* Run the job start callbacks
|
363
|
+
*
|
364
|
+
* @param string $handle The job's Gearman handle
|
365
|
+
* @param string $job The name of the job
|
366
|
+
* @param mixed $args The job's argument list
|
367
|
+
*
|
368
|
+
* @return void
|
369
|
+
*/
|
370
|
+
protected function start($handle, $job, $args)
|
371
|
+
{
|
372
|
+
if (!count($this->callback[self::JOB_START])) {
|
373
|
+
return; // No callbacks to run
|
374
|
+
}
|
375
|
+
|
376
|
+
foreach ($this->callback[self::JOB_START] as $callback) {
|
377
|
+
call_user_func($callback, $handle, $job, $args);
|
378
|
+
}
|
379
|
+
}
|
380
|
+
|
381
|
+
/**
|
382
|
+
* Run the complete callbacks
|
383
|
+
*
|
384
|
+
* @param string $handle The job's Gearman handle
|
385
|
+
* @param string $job The name of the job
|
386
|
+
* @param array $result The job's returned result
|
387
|
+
*
|
388
|
+
* @return void
|
389
|
+
*/
|
390
|
+
protected function complete($handle, $job, array $result)
|
391
|
+
{
|
392
|
+
if (!count($this->callback[self::JOB_COMPLETE])) {
|
393
|
+
return; // No callbacks to run
|
394
|
+
}
|
395
|
+
|
396
|
+
foreach ($this->callback[self::JOB_COMPLETE] as $callback) {
|
397
|
+
call_user_func($callback, $handle, $job, $result);
|
398
|
+
}
|
399
|
+
}
|
400
|
+
|
401
|
+
/**
|
402
|
+
* Run the fail callbacks
|
403
|
+
*
|
404
|
+
* @param string $handle The job's Gearman handle
|
405
|
+
* @param string $job The name of the job
|
406
|
+
* @param object $error The exception thrown
|
407
|
+
*
|
408
|
+
* @return void
|
409
|
+
*/
|
410
|
+
protected function fail($handle, $job, PEAR_Exception $error)
|
411
|
+
{
|
412
|
+
if (!count($this->callback[self::JOB_FAIL])) {
|
413
|
+
return; // No callbacks to run
|
414
|
+
}
|
415
|
+
|
416
|
+
foreach ($this->callback[self::JOB_FAIL] as $callback) {
|
417
|
+
call_user_func($callback, $handle, $job, $error);
|
418
|
+
}
|
419
|
+
}
|
420
|
+
|
421
|
+
/**
|
422
|
+
* Stop working
|
423
|
+
*
|
424
|
+
* @return void
|
425
|
+
*/
|
426
|
+
public function endWork()
|
427
|
+
{
|
428
|
+
foreach ($this->conn as $conn) {
|
429
|
+
Net_Gearman_Connection::close($conn);
|
430
|
+
}
|
431
|
+
}
|
432
|
+
|
433
|
+
/**
|
434
|
+
* Destructor
|
435
|
+
*
|
436
|
+
* @return void
|
437
|
+
* @see Net_Gearman_Worker::stop()
|
438
|
+
*/
|
439
|
+
public function __destruct()
|
440
|
+
{
|
441
|
+
$this->endWork();
|
442
|
+
}
|
443
|
+
|
444
|
+
/**
|
445
|
+
* Should we stop work?
|
446
|
+
*
|
447
|
+
* @return boolean
|
448
|
+
*/
|
449
|
+
public function stopWork()
|
450
|
+
{
|
451
|
+
return false;
|
452
|
+
}
|
453
|
+
}
|
454
|
+
|
455
|
+
?>
|
data/examples/client.php
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
require_once 'Net/Gearman/Client.php';
|
4
|
+
|
5
|
+
$set = new Net_Gearman_Set();
|
6
|
+
|
7
|
+
function result($func, $handle, $result) {
|
8
|
+
var_dump($func);
|
9
|
+
var_dump($handle);
|
10
|
+
var_dump($result);
|
11
|
+
}
|
12
|
+
|
13
|
+
$task = new Net_Gearman_Task('Sleep', array(
|
14
|
+
'seconds' => 20
|
15
|
+
));
|
16
|
+
|
17
|
+
$task->attachCallback('result');
|
18
|
+
$set->addTask($task);
|
19
|
+
|
20
|
+
$client = new Net_Gearman_Client(array('localhost:4730', 'localhost:4731'));
|
21
|
+
$client->runSet($set);
|
22
|
+
|
23
|
+
?>
|
data/examples/client.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
#require 'gearman'
|
3
|
+
require '../lib/gearman'
|
4
|
+
Gearman::Util.debug = true
|
5
|
+
|
6
|
+
servers = ['localhost:4730', 'localhost:4731']
|
7
|
+
|
8
|
+
client = Gearman::Client.new(servers)
|
9
|
+
taskset = Gearman::TaskSet.new(client)
|
10
|
+
|
11
|
+
task = Gearman::Task.new('sleep', 20)
|
12
|
+
task.on_complete {|d| puts d }
|
13
|
+
|
14
|
+
taskset.add_task(task)
|
15
|
+
taskset.wait(100)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
$: << '../lib'
|
4
|
+
require 'gearman'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
Gearman::Util.debug = true
|
8
|
+
servers = 'localhost:7003'
|
9
|
+
format = 'PNG'
|
10
|
+
width, height = 100, 100
|
11
|
+
|
12
|
+
opts = OptionParser.new
|
13
|
+
opts.banner = "Usage: #{$0} [options] <input> <output>"
|
14
|
+
opts.on('-f FORMAT', '--format', 'Scaled image format') { format }
|
15
|
+
opts.on('-h HEIGHT', '--height', 'Scaled image height') { height }
|
16
|
+
opts.on('-s SERVERS', '--servers',
|
17
|
+
'Servers, comma-separated host:port') { servers }
|
18
|
+
opts.on('-w WIDTH', '--width', 'Scaled image width') { width }
|
19
|
+
opts.parse!
|
20
|
+
|
21
|
+
if ARGV.size != 2
|
22
|
+
$stderr.puts opts.banner
|
23
|
+
exit 1
|
24
|
+
end
|
25
|
+
|
26
|
+
client = Gearman::Client.new(servers.split(','), 'example')
|
27
|
+
taskset = Gearman::TaskSet.new(client)
|
28
|
+
arg = [width, height, format, File.read(ARGV[0])].join("\0")
|
29
|
+
task = Gearman::Task.new('scale_image', arg)
|
30
|
+
task.on_complete {|d| File.new(ARGV[1],'w').write(d) }
|
31
|
+
taskset.add_task(task)
|
32
|
+
taskset.wait(10)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
$: << '../lib'
|
4
|
+
require 'gearman'
|
5
|
+
require 'optparse'
|
6
|
+
require 'RMagick'
|
7
|
+
|
8
|
+
Gearman::Util.debug = true
|
9
|
+
servers = 'localhost:7003'
|
10
|
+
|
11
|
+
opts = OptionParser.new
|
12
|
+
opts.banner = "Usage: #{$0} [options]"
|
13
|
+
opts.on('-s SERVERS', '--servers',
|
14
|
+
'Job servers, comma-separated host:port') { servers }
|
15
|
+
opts.parse!
|
16
|
+
|
17
|
+
worker = Gearman::Worker.new(servers.split(','), 'example')
|
18
|
+
|
19
|
+
worker.add_ability('scale_image') do |data,job|
|
20
|
+
width, height, format, data = data.split("\0", 4)
|
21
|
+
width = width.to_f
|
22
|
+
height = height.to_f
|
23
|
+
image = Magick::Image.from_blob(data)[0]
|
24
|
+
orig_ratio = image.columns.to_f / image.rows
|
25
|
+
new_ratio = width / height
|
26
|
+
w = new_ratio < orig_ratio ? width : orig_ratio / new_ratio * width
|
27
|
+
h = new_ratio > orig_ratio ? height : new_ratio / orig_ratio * height
|
28
|
+
puts "Got #{image.inspect}; resizing to #{w}x#{h} #{format}"
|
29
|
+
image.resize!(w, h)
|
30
|
+
image.format = format
|
31
|
+
image.to_blob
|
32
|
+
end
|
33
|
+
|
34
|
+
loop { worker.work }
|
data/examples/server.rb
ADDED
data/examples/worker.php
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
<?php
|
2
|
+
error_reporting(E_ALL & ~E_NOTICE);
|
3
|
+
|
4
|
+
require_once 'Net/Gearman/Worker.php';
|
5
|
+
|
6
|
+
try {
|
7
|
+
$worker = new Net_Gearman_Worker(array('localhost:4730'));
|
8
|
+
$worker->addAbility('Sleep');
|
9
|
+
$worker->beginWork();
|
10
|
+
} catch (Net_Gearman_Exception $e) {
|
11
|
+
echo $e->getMessage() . "\n";
|
12
|
+
exit;
|
13
|
+
}
|
14
|
+
|
15
|
+
?>
|
data/examples/worker.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
#require 'gearman'
|
3
|
+
require '../lib/gearman'
|
4
|
+
|
5
|
+
Gearman::Util.debug = true
|
6
|
+
|
7
|
+
servers = ['localhost:4730', 'localhost:4731']
|
8
|
+
w = Gearman::Worker.new(servers)
|
9
|
+
|
10
|
+
# Add a handler for a "sleep" function that takes a single argument, the
|
11
|
+
# number of seconds to sleep before reporting success.
|
12
|
+
w.add_ability('sleep') do |data,job|
|
13
|
+
seconds = data
|
14
|
+
(1..seconds.to_i).each do |i|
|
15
|
+
sleep 1
|
16
|
+
print i
|
17
|
+
# Report our progress to the job server every second.
|
18
|
+
job.report_status(i, seconds)
|
19
|
+
end
|
20
|
+
# Report success.
|
21
|
+
true
|
22
|
+
end
|
23
|
+
loop { w.work }
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{gearman-ruby}
|
5
|
+
s.version = "1.0.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Daniel Erat", "Ladislav Martincik"]
|
9
|
+
s.date = %q{2009-06-25}
|
10
|
+
s.description = %q{Library for the Gearman distributed job system}
|
11
|
+
s.email = %q{ladislav.martincik@xing.com}
|
12
|
+
s.extra_rdoc_files = [
|
13
|
+
"LICENSE",
|
14
|
+
"README"
|
15
|
+
]
|
16
|
+
s.files = [
|
17
|
+
".gitignore",
|
18
|
+
"LICENSE",
|
19
|
+
"README",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION.yml",
|
22
|
+
"examples/Net/Gearman/Client.php",
|
23
|
+
"examples/Net/Gearman/Connection.php",
|
24
|
+
"examples/Net/Gearman/Exception.php",
|
25
|
+
"examples/Net/Gearman/Job.php",
|
26
|
+
"examples/Net/Gearman/Job/Common.php",
|
27
|
+
"examples/Net/Gearman/Job/Exception.php",
|
28
|
+
"examples/Net/Gearman/Job/Sleep.php",
|
29
|
+
"examples/Net/Gearman/Manager.php",
|
30
|
+
"examples/Net/Gearman/Set.php",
|
31
|
+
"examples/Net/Gearman/Task.php",
|
32
|
+
"examples/Net/Gearman/Worker.php",
|
33
|
+
"examples/client.php",
|
34
|
+
"examples/client.rb",
|
35
|
+
"examples/scale_image.rb",
|
36
|
+
"examples/scale_image_worker.rb",
|
37
|
+
"examples/server.rb",
|
38
|
+
"examples/worker.php",
|
39
|
+
"examples/worker.rb",
|
40
|
+
"gearman-ruby.gemspec",
|
41
|
+
"lib/gearman.rb",
|
42
|
+
"lib/gearman/client.rb",
|
43
|
+
"lib/gearman/server.rb",
|
44
|
+
"lib/gearman/task.rb",
|
45
|
+
"lib/gearman/taskset.rb",
|
46
|
+
"lib/gearman/testlib.rb",
|
47
|
+
"lib/gearman/util.rb",
|
48
|
+
"lib/gearman/worker.rb",
|
49
|
+
"test/client_test.rb",
|
50
|
+
"test/mock_client_test.rb",
|
51
|
+
"test/mock_worker_test.rb",
|
52
|
+
"test/worker_test.rb"
|
53
|
+
]
|
54
|
+
s.has_rdoc = true
|
55
|
+
s.homepage = %q{http://github.com/xing/gearman-ruby}
|
56
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
57
|
+
s.require_paths = ["lib"]
|
58
|
+
s.rubygems_version = %q{1.3.1}
|
59
|
+
s.summary = %q{Library for the Gearman distributed job system}
|
60
|
+
s.test_files = [
|
61
|
+
"test/client_test.rb",
|
62
|
+
"test/mock_client_test.rb",
|
63
|
+
"test/mock_worker_test.rb",
|
64
|
+
"test/worker_test.rb",
|
65
|
+
"examples/client.rb",
|
66
|
+
"examples/scale_image.rb",
|
67
|
+
"examples/scale_image_worker.rb",
|
68
|
+
"examples/server.rb",
|
69
|
+
"examples/worker.rb"
|
70
|
+
]
|
71
|
+
|
72
|
+
if s.respond_to? :specification_version then
|
73
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
74
|
+
s.specification_version = 2
|
75
|
+
|
76
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
77
|
+
else
|
78
|
+
end
|
79
|
+
else
|
80
|
+
end
|
81
|
+
end
|