|
1 | 1 | # Bow Scheduler |
2 | 2 |
|
3 | | -The Bow Scheduler provides a simple and elegant way to define scheduled tasks. It offers four main methods to schedule different types of jobs: |
4 | | - |
5 | | -- **`command()`** - Run Bow console commands |
6 | | -- **`task()`** - Run QueueTask classes |
7 | | -- **`exec()`** - Run bash/shell commands |
8 | | -- **`call()`** - Run closures/callbacks |
9 | | - |
10 | | -## Configuration |
11 | | - |
12 | | -Define your scheduled events in the `routes/scheduler.php` file: |
13 | | - |
14 | | -```php |
15 | | -<?php |
16 | | - |
17 | | -use Bow\Scheduler\Scheduler; |
18 | | - |
19 | | -// Get the scheduler instance |
20 | | -$scheduler = Scheduler::getInstance(); |
21 | | - |
22 | | -// Schedule a Bow console command |
23 | | -$scheduler->command('cache:clear') |
24 | | - ->daily() |
25 | | - ->dailyAt('02:00') |
26 | | - ->description('Clear application cache'); |
27 | | - |
28 | | -// Schedule a shell command |
29 | | -$scheduler->exec('mysqldump -u root mydb > /backups/db.sql') |
30 | | - ->daily() |
31 | | - ->dailyAt('03:00') |
32 | | - ->description('Backup database') |
33 | | - ->runInBackground(); |
34 | | - |
35 | | -// Schedule a closure |
36 | | -$scheduler->call(function () { |
37 | | - logger('Cleanup task ran...'); |
38 | | -}) |
39 | | - ->hourly() |
40 | | - ->description('Cleanup task'); |
41 | | - |
42 | | -// Schedule a QueueTask |
43 | | -$scheduler->task(App\Tasks\SendWeeklyReportTask::class) |
44 | | - ->weekly() |
45 | | - ->sundays() |
46 | | - ->dailyAt('10:00') |
47 | | - ->onConnection('redis') |
48 | | - ->description('Send weekly reports'); |
49 | | -``` |
50 | | - |
51 | | -The scheduler automatically loads this file when running scheduler commands. |
52 | | - |
53 | | -## Available Methods |
54 | | - |
55 | | -### `command(string $command, array $parameters = []): Schedule` |
56 | | - |
57 | | -Schedule a Bow console command to run: |
58 | | - |
59 | | -```php |
60 | | -// Simple command |
61 | | -$scheduler->command('migration:migrate')->daily(); |
62 | | - |
63 | | -// Command with parameters |
64 | | -$scheduler->command('email:send', ['--to' => 'admin@example.com'])->hourly(); |
65 | | -``` |
66 | | - |
67 | | -### `task(string|QueueTask $task, array $parameters = []): Schedule` |
68 | | - |
69 | | -Schedule a QueueTask class to run: |
70 | | - |
71 | | -```php |
72 | | -// By class name |
73 | | -$scheduler->task(App\Tasks\ProcessReportsTask::class)->daily(); |
74 | | - |
75 | | -// With constructor parameters |
76 | | -$scheduler->task(App\Tasks\SendNotificationTask::class, ['user', 'message'])->hourly(); |
77 | | - |
78 | | -// With an instance |
79 | | -$task = new App\Tasks\GenerateStats($config); |
80 | | -$scheduler->task($task)->weekly(); |
81 | | -``` |
82 | | - |
83 | | -### `exec(string $command, array $parameters = []): Schedule` |
84 | | - |
85 | | -Schedule a shell/bash command: |
86 | | - |
87 | | -```php |
88 | | -$scheduler->exec('rm -rf /tmp/cache/*')->daily()->at('04:00'); |
89 | | - |
90 | | -// With parameters (automatically escaped) |
91 | | -$scheduler->exec('tar -czf backup.tar.gz', ['/var/www/files'])->weekly(); |
92 | | -``` |
93 | | - |
94 | | -### `call(callable $callback, array $parameters = []): Schedule` |
95 | | - |
96 | | -Schedule a closure or callback: |
97 | | - |
98 | | -```php |
99 | | -$scheduler->call(function () { |
100 | | - // Your code here |
101 | | -})->everyFiveMinutes(); |
102 | | - |
103 | | -// With parameters |
104 | | -$scheduler->call(function ($name, $email) { |
105 | | - logger("Processing: {$name} ({$email})"); |
106 | | -}, ['John', 'john@example.com'])->hourly(); |
107 | | -``` |
108 | | - |
109 | | -## Schedule Frequencies |
110 | | - |
111 | | -Available frequency methods: |
112 | | - |
113 | | -| Method | Description | |
114 | | -|--------|-------------| |
115 | | -| `everyMinute()` | Run every minute | |
116 | | -| `everyTwoMinutes()` | Run every 2 minutes | |
117 | | -| `everyFiveMinutes()` | Run every 5 minutes | |
118 | | -| `everyTenMinutes()` | Run every 10 minutes | |
119 | | -| `everyFifteenMinutes()` | Run every 15 minutes | |
120 | | -| `everyThirtyMinutes()` | Run every 30 minutes | |
121 | | -| `hourly()` | Run every hour | |
122 | | -| `hourlyAt(17)` | Run hourly at 17 minutes past | |
123 | | -| `daily()` | Run daily at midnight | |
124 | | -| `dailyAt('13:00')` | Run daily at 13:00 | |
125 | | -| `twiceDaily(1, 13)` | Run daily at 1:00 and 13:00 | |
126 | | -| `weekly()` | Run weekly on Sunday | |
127 | | -| `weeklyOn(1, '8:00')` | Run weekly on Monday at 8:00 | |
128 | | -| `monthly()` | Run monthly on the 1st at midnight | |
129 | | -| `monthlyOn(15, '15:00')` | Run monthly on the 15th at 15:00 | |
130 | | -| `quarterly()` | Run quarterly | |
131 | | -| `yearly()` | Run yearly | |
132 | | -| `cron('* * * * *')` | Define a custom cron expression | |
133 | | - |
134 | | -### Day Constraints |
135 | | - |
136 | | -```php |
137 | | -$scheduler->command('report:generate') |
138 | | - ->daily() |
139 | | - ->weekdays(); // Only on weekdays |
140 | | - |
141 | | -$scheduler->command('cleanup') |
142 | | - ->daily() |
143 | | - ->weekends(); // Only on weekends |
144 | | - |
145 | | -$scheduler->command('backup') |
146 | | - ->daily() |
147 | | - ->mondays(); // Only on Mondays |
148 | | -``` |
149 | | - |
150 | | -## Advanced Options |
151 | | - |
152 | | -### Background Execution |
153 | | - |
154 | | -For long-running commands, run in the background: |
| 3 | +Define scheduled tasks in your `App\Kernel::schedules()` method: |
155 | 4 |
|
156 | 5 | ```php |
157 | | -$scheduler->exec('php process-heavy-task.php') |
158 | | - ->daily() |
159 | | - ->runInBackground(); |
160 | | -``` |
161 | | - |
162 | | -### Overlap Prevention |
163 | | - |
164 | | -Prevent a scheduled event from running if a previous instance is still running: |
165 | | - |
166 | | -```php |
167 | | -$scheduler->command('slow:process') |
168 | | - ->hourly() |
169 | | - ->withoutOverlapping(60); // Lock expires after 60 minutes |
170 | | -``` |
171 | | - |
172 | | -### Conditional Scheduling |
173 | | - |
174 | | -Run events only when conditions are met: |
175 | | - |
176 | | -```php |
177 | | -$scheduler->command('send:emails') |
178 | | - ->daily() |
179 | | - ->when(function () { |
180 | | - return app()->environment('production'); |
181 | | - }); |
182 | | - |
183 | | -$scheduler->command('debug:task') |
184 | | - ->daily() |
185 | | - ->skip(function () { |
186 | | - return app()->environment('production'); |
187 | | - }); |
188 | | -``` |
189 | | - |
190 | | -### Event Callbacks |
191 | | - |
192 | | -Execute callbacks before, after, or on failure: |
193 | | - |
194 | | -```php |
195 | | -$scheduler->command('important:task') |
196 | | - ->daily() |
197 | | - ->before(function ($event) { |
198 | | - logger('Starting important task...'); |
199 | | - }) |
200 | | - ->after(function ($event) { |
201 | | - logger('Task completed!'); |
202 | | - }) |
203 | | - ->onFailure(function ($event, $exception) { |
204 | | - logger("Task failed: " . $exception->getMessage()); |
205 | | - }); |
206 | | -``` |
207 | | - |
208 | | -### Timezone |
209 | | - |
210 | | -Set a specific timezone for the schedule: |
211 | | - |
212 | | -```php |
213 | | -$scheduler->command('report:generate') |
214 | | - ->daily() |
215 | | - ->at('09:00') |
216 | | - ->timezone('America/New_York'); |
| 6 | +public function schedules(Scheduler $schedule): void |
| 7 | +{ |
| 8 | + $schedule->command('cache:clear')->daily(); |
| 9 | + $schedule->exec('mysqldump mydb > backup.sql')->daily()->at('03:00'); |
| 10 | + $schedule->call(fn () => logger('Heartbeat'))->everyMinute(); |
| 11 | + $schedule->task(SendReportTask::class)->weekly()->sundays(); |
| 12 | +} |
217 | 13 | ``` |
218 | 14 |
|
219 | 15 | ## Console Commands |
220 | 16 |
|
221 | | -### Run Due Events |
222 | | - |
223 | | -Run all events that are due: |
224 | | - |
225 | | -```bash |
226 | | -php bow schedule:run |
227 | | -``` |
228 | | - |
229 | | -### Start Scheduler Daemon |
230 | | - |
231 | | -Start a continuous scheduler (typically in production): |
232 | | - |
233 | 17 | ```bash |
234 | | -php bow schedule:work |
| 18 | +php bow schedule:list # List all tasks |
| 19 | +php bow schedule:run # Run due tasks once |
| 20 | +php bow schedule:work # Start daemon (continuous) |
235 | 21 | ``` |
236 | 22 |
|
237 | | -### List Events |
238 | | - |
239 | | -List all registered scheduled events: |
| 23 | +## Production (Cron) |
240 | 24 |
|
241 | 25 | ```bash |
242 | | -php bow schedule:list |
243 | | -``` |
244 | | - |
245 | | -### Show Next Run Times |
246 | | - |
247 | | -Show when each event will next run: |
248 | | - |
249 | | -```bash |
250 | | -php bow schedule:next |
251 | | -``` |
252 | | - |
253 | | -### Test an Event |
254 | | - |
255 | | -Test run an event by its index (0-based): |
256 | | - |
257 | | -```bash |
258 | | -php bow schedule:test 0 |
259 | | -``` |
260 | | - |
261 | | -## Production Setup |
262 | | - |
263 | | -In production, add a cron entry that runs the scheduler every minute: |
264 | | - |
265 | | -```bash |
266 | | -* * * * * cd /path-to-your-project && php bow schedule:run >> /dev/null 2>&1 |
267 | | -``` |
268 | | - |
269 | | -Or use the daemon mode (recommended for better performance): |
270 | | - |
271 | | -```bash |
272 | | -php bow schedule:work |
273 | | -``` |
274 | | - |
275 | | -For daemon mode, consider using a process manager like Supervisor: |
276 | | - |
277 | | -```ini |
278 | | -[program:scheduler] |
279 | | -process_name=%(program_name)s |
280 | | -directory=/var/www/your-app |
281 | | -command=php bow schedule:work |
282 | | -autostart=true |
283 | | -autorestart=true |
284 | | -user=www-data |
285 | | -redirect_stderr=true |
286 | | -stdout_logfile=/var/log/scheduler.log |
287 | | -``` |
288 | | - |
289 | | -## Example: Complete Application Setup |
290 | | - |
291 | | -```php |
292 | | -<?php |
293 | | - |
294 | | -// app/Configurations/SchedulerConfiguration.php |
295 | | - |
296 | | -namespace App\Configurations; |
297 | | - |
298 | | -use Bow\Configuration\Configuration; |
299 | | -use Bow\Scheduler\Scheduler; |
300 | | - |
301 | | -class SchedulerConfiguration extends Configuration |
302 | | -{ |
303 | | - public function create(\Bow\Configuration\Loader $config): void |
304 | | - { |
305 | | - // Nothing to configure |
306 | | - } |
307 | | - |
308 | | - public function run(): void |
309 | | - { |
310 | | - $scheduler = app('scheduler'); |
311 | | - |
312 | | - // Daily database backup |
313 | | - $scheduler->exec('mysqldump mydb > /backups/daily.sql') |
314 | | - ->daily() |
315 | | - ->at('01:00') |
316 | | - ->description('Daily database backup'); |
317 | | - |
318 | | - // Clear cache every Sunday |
319 | | - $scheduler->command('cache:clear') |
320 | | - ->weekly() |
321 | | - ->sundays() |
322 | | - ->at('02:00') |
323 | | - ->description('Weekly cache clear'); |
324 | | - |
325 | | - // Process pending reports every hour |
326 | | - $scheduler->task(\App\Tasks\ProcessPendingReportsTask::class) |
327 | | - ->hourly() |
328 | | - ->description('Process pending reports'); |
329 | | - |
330 | | - // Check system health every 5 minutes |
331 | | - $scheduler->call(function () { |
332 | | - $health = \App\Services\HealthChecker::check(); |
333 | | - if (!$health->isHealthy()) { |
334 | | - \App\Services\AlertService::notify($health); |
335 | | - } |
336 | | - }) |
337 | | - ->everyFiveMinutes() |
338 | | - ->description('Health check'); |
339 | | - } |
340 | | -} |
| 26 | +* * * * * cd /path-to-project && php bow schedule:run >> /dev/null 2>&1 |
341 | 27 | ``` |
0 commit comments