Skip to content

Commit 23fbc2e

Browse files
authored
Merge pull request #19 from M2Mobi/scheduler
Integrate php-resque-scheduler
2 parents 25ff307 + 2f725b6 commit 23fbc2e

7 files changed

+592
-2
lines changed

README.md

+82
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ It also supports the following additional features:
5656
- Has built in support for `setUp` and `tearDown` methods, called pre and post
5757
jobs
5858

59+
Additionally it includes php-resque-scheduler, a PHP port of [resque-scheduler](http://github.com/resque/resque),
60+
which adds support for scheduling items in the future to Resque. It has been
61+
designed to be an almost direct-copy of the Ruby plugin
62+
63+
At the moment, php-resque-scheduler only supports delayed jobs, which is the
64+
ability to push a job to the queue and have it run at a certain timestamp, or
65+
in a number of seconds. Support for recurring jobs (similar to CRON) is planned
66+
for a future release.
67+
5968
This port was originally made by [Chris
6069
Boulton](https://github.com/chrisboulton), with maintenance by the community.
6170
See <https://github.com/chrisboulton/php-resque> for more on that history.
@@ -218,6 +227,43 @@ echo Resque_Job_PID::get($token);
218227

219228
Function returns `0` if the `perform` hasn't started yet, or if it has already ended.
220229

230+
## Delayed Jobs
231+
232+
To quote the documentation for the Ruby resque-scheduler:
233+
234+
> Delayed jobs are one-off jobs that you want to be put into a queue at some
235+
point in the future. The classic example is sending an email:
236+
237+
require 'Resque/Resque.php';
238+
require 'ResqueScheduler/ResqueScheduler.php';
239+
240+
$in = 3600;
241+
$args = array('id' => $user->id);
242+
ResqueScheduler::enqueueIn($in, 'email', 'SendFollowUpEmail', $args);
243+
244+
The above will store the job for 1 hour in the delayed queue, and then pull the
245+
job off and submit it to the `email` queue in Resque for processing as soon as
246+
a worker is available.
247+
248+
Instead of passing a relative time in seconds, you can also supply a timestamp
249+
as either a DateTime object or integer containing a UNIX timestamp to the
250+
`enqueueAt` method:
251+
252+
require 'Resque/Resque.php';
253+
require 'ResqueScheduler/ResqueScheduler.php';
254+
255+
$time = 1332067214;
256+
ResqueScheduler::enqueueAt($time, 'email', 'SendFollowUpEmail', $args);
257+
258+
$datetime = new DateTime('2012-03-18 13:21:49');
259+
ResqueScheduler::enqueueAt($datetime, 'email', 'SendFollowUpEmail', $args);
260+
261+
NOTE: resque-scheduler does not guarantee a job will fire at the time supplied.
262+
At the time supplied, resque-scheduler will take the job out of the delayed
263+
queue and push it to the appropriate queue in Resque. Your next available Resque
264+
worker will pick the job up. To keep processing as quick as possible, keep your
265+
queues as empty as possible.
266+
221267
## Workers
222268

223269
Workers work in the exact same way as the Ruby workers. For complete
@@ -355,6 +401,29 @@ functionality to PHP before 5.5, so if you'd like process titles updated,
355401
install the PECL module as well. php-resque will automatically detect and use
356402
it.
357403

404+
### Resque Scheduler
405+
406+
resque-scheduler requires a special worker that runs in the background. This
407+
worker is responsible for pulling items off the schedule/delayed queue and adding
408+
them to the queue for resque. This means that for delayed or scheduled jobs to be
409+
executed, that worker needs to be running.
410+
411+
A basic "up-and-running" `bin/resque-scheduler` file that sets up a
412+
running worker environment is included (`vendor/bin/resque-scheduler` when
413+
installed via composer). It accepts many of the same environment variables as
414+
the main workers for php-resque:
415+
416+
* `REDIS_BACKEND` - Redis server to connect to
417+
* `LOGGING` - Enable logging to STDOUT
418+
* `VERBOSE` - Enable verbose logging
419+
* `VVERBOSE` - Enable very verbose logging
420+
* `INTERVAL` - Sleep for this long before checking scheduled/delayed queues
421+
* `APP_INCLUDE` - Include this file when starting (to launch your app)
422+
* `PIDFILE` - Write the PID of the worker out to this file
423+
424+
It's easy to start the resque-scheduler worker using `bin/resque-scheduler`:
425+
$ php bin/resque-scheduler
426+
358427
## Event/Hook System
359428

360429
php-resque has a basic event system that can be used by your application to
@@ -462,6 +531,17 @@ passed (in this order) include:
462531
- Queue - string containing the name of the queue the job was added to
463532
- ID - string containing the new token of the enqueued job
464533

534+
### afterSchedule
535+
536+
Called after a job has been added to the schedule. Arguments passed are the
537+
timestamp, queue of the job, the class name of the job, and the job's arguments.
538+
539+
### beforeDelayedEnqueue
540+
541+
Called immediately after a job has been pulled off the delayed queue and right
542+
before the job is added to the queue in resque. Arguments passed are the queue
543+
of the job, the class name of the job, and the job's arguments.
544+
465545
## Step-By-Step
466546

467547
For a more in-depth look at what php-resque does under the hood (without needing
@@ -486,6 +566,7 @@ to directly examine the code), have a look at `HOWITWORKS.md`.
486566
- @andrewjshults
487567
- @atorres757
488568
- @benjisg
569+
- @biinari
489570
- @cballou
490571
- @chaitanyakuber
491572
- @charly22
@@ -511,6 +592,7 @@ to directly examine the code), have a look at `HOWITWORKS.md`.
511592
- @patrickbajao
512593
- @pedroarnal
513594
- @ptrofimov
595+
- @rayward
514596
- @richardkmiller
515597
- @Rockstar04
516598
- @ruudk

bin/resque-scheduler

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
// Find and initialize Composer
5+
$files = array(
6+
__DIR__ . '/../../vendor/autoload.php',
7+
__DIR__ . '/../../../autoload.php',
8+
__DIR__ . '/../../../../autoload.php',
9+
__DIR__ . '/../vendor/autoload.php',
10+
);
11+
12+
$found = false;
13+
foreach ($files as $file) {
14+
if (file_exists($file)) {
15+
require_once $file;
16+
break;
17+
}
18+
}
19+
20+
if (!class_exists('Composer\Autoload\ClassLoader', false)) {
21+
die(
22+
'You need to set up the project dependencies using the following commands:' . PHP_EOL .
23+
'curl -s http://getcomposer.org/installer | php' . PHP_EOL .
24+
'php composer.phar install' . PHP_EOL
25+
);
26+
}
27+
28+
$REDIS_BACKEND = getenv('REDIS_BACKEND');
29+
$REDIS_BACKEND_DB = getenv('REDIS_BACKEND_DB');
30+
if(!empty($REDIS_BACKEND)) {
31+
if (empty($REDIS_BACKEND_DB))
32+
Resque::setBackend($REDIS_BACKEND);
33+
else
34+
Resque::setBackend($REDIS_BACKEND, $REDIS_BACKEND_DB);
35+
}
36+
37+
// Set log level for resque-scheduler
38+
$logLevel = 0;
39+
$LOGGING = getenv('LOGGING');
40+
$VERBOSE = getenv('VERBOSE');
41+
$VVERBOSE = getenv('VVERBOSE');
42+
if(!empty($LOGGING) || !empty($VERBOSE)) {
43+
$logLevel = ResqueScheduler_Worker::LOG_NORMAL;
44+
}
45+
else if(!empty($VVERBOSE)) {
46+
$logLevel = ResqueScheduler_Worker::LOG_VERBOSE;
47+
}
48+
49+
// Check for jobs every $interval seconds
50+
$interval = 5;
51+
$INTERVAL = getenv('INTERVAL');
52+
if(!empty($INTERVAL)) {
53+
$interval = $INTERVAL;
54+
}
55+
56+
// Load the user's application if one exists
57+
$APP_INCLUDE = getenv('APP_INCLUDE');
58+
if($APP_INCLUDE) {
59+
if(!file_exists($APP_INCLUDE)) {
60+
die('APP_INCLUDE ('.$APP_INCLUDE.") does not exist.\n");
61+
}
62+
63+
require_once $APP_INCLUDE;
64+
}
65+
66+
$PREFIX = getenv('PREFIX');
67+
if(!empty($PREFIX)) {
68+
fwrite(STDOUT, '*** Prefix set to '.$PREFIX."\n");
69+
Resque_Redis::prefix($PREFIX);
70+
}
71+
72+
$worker = new ResqueScheduler_Worker();
73+
$worker->logLevel = $logLevel;
74+
75+
$PIDFILE = getenv('PIDFILE');
76+
if ($PIDFILE) {
77+
file_put_contents($PIDFILE, getmypid()) or
78+
die('Could not write PID information to ' . $PIDFILE);
79+
}
80+
81+
fwrite(STDOUT, "*** Starting scheduler worker\n");
82+
$worker->work($interval);

composer.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@
4141
"phpunit/phpunit": "3.7.*"
4242
},
4343
"bin": [
44-
"bin/resque"
44+
"bin/resque",
45+
"bin/resque-scheduler"
4546
],
4647
"autoload": {
4748
"psr-0": {
48-
"Resque": "lib"
49+
"Resque": "lib",
50+
"ResqueScheduler": "lib"
4951
}
5052
},
5153
"extra": {

extras/resque-scheduler.monit

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Replace these with your own:
2+
# [PATH/TO/RESQUE]
3+
# [PATH/TO/RESQUE-SCHEDULER]
4+
# [UID]
5+
# [GID]
6+
# [APP_INCLUDE]
7+
8+
check process resque-scheduler_worker
9+
with pidfile /var/run/resque/scheduler-worker.pid
10+
start program = "/bin/sh -c 'APP_INCLUDE=[APP_INCLUDE] RESQUE_PHP=[PATH/TO/RESQUE] PIDFILE=/var/run/resque/scheduler-worker.pid nohup php -f [PATH/TO/RESQUE-SCHEDULER]/resque-scheduler.php > /var/log/resque/scheduler-worker.log &'" as uid [UID] and gid [GID]
11+
stop program = "/bin/sh -c 'kill -s QUIT `cat /var/run/resque/scheduler-worker.pid` && rm -f /var/run/resque/scheduler-worker.pid; exit 0;'"
12+
if totalmem is greater than 300 MB for 10 cycles then restart # eating up memory?
13+
group resque-scheduler_workers

0 commit comments

Comments
 (0)