• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

daycry / jobs / 21145580946

19 Jan 2026 04:55PM UTC coverage: 58.025% (-4.5%) from 62.567%
21145580946

push

github

daycry
Add security, performance, and health features; simplify architecture

Introduces shell command whitelisting, smart token detection, per-queue rate limiting, dead letter queue, job timeout protection, config caching, and a health monitoring command. Refactors architecture by consolidating traits, removing the CompletionStrategy pattern, and unifying retry policies under RetryPolicyFixed. Updates documentation and tests to reflect new features and architectural changes, ensuring backward compatibility and improved reliability.

143 of 340 new or added lines in 20 files covered. (42.06%)

1 existing line in 1 file now uncovered.

1193 of 2056 relevant lines covered (58.03%)

4.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Commands/HealthCheckCommand.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of Daycry Queues.
7
 *
8
 * (c) Daycry <daycry9@proton.me>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace Daycry\Jobs\Commands;
15

16
use CodeIgniter\CLI\BaseCommand;
17
use CodeIgniter\CLI\CLI;
18
use Daycry\Jobs\Libraries\RateLimiter;
19
use Daycry\Jobs\Models\JobsLogModel;
20
use Daycry\Jobs\Models\QueueModel;
21

22
/**
23
 * Health check command for monitoring queue system status.
24
 * Provides statistics about queues, workers, and job processing.
25
 */
26
class HealthCheckCommand extends BaseCommand
27
{
28
    protected $group       = 'Jobs';
29
    protected $name        = 'jobs:health';
30
    protected $description = 'Display health check and statistics for the Jobs system';
31
    protected $usage       = 'jobs:health [options]';
32
    protected $arguments   = [];
33
    protected $options     = [
34
        '--json'  => 'Output as JSON',
35
        '--queue' => 'Check specific queue',
36
    ];
37

38
    public function run(array $params): void
39
    {
NEW
40
        $json          = CLI::getOption('json');
×
NEW
41
        $specificQueue = CLI::getOption('queue');
×
42

NEW
43
        $stats = $this->collectStats($specificQueue);
×
44

NEW
45
        if ($json) {
×
NEW
46
            CLI::write(json_encode($stats, JSON_PRETTY_PRINT));
×
47
        } else {
NEW
48
            $this->displayStats($stats);
×
49
        }
50
    }
51

52
    private function collectStats(?string $specificQueue = null): array
53
    {
NEW
54
        $config      = config('Jobs');
×
NEW
55
        $queueModel  = new QueueModel();
×
NEW
56
        $logModel    = model(JobsLogModel::class);
×
NEW
57
        $rateLimiter = new RateLimiter();
×
58

NEW
59
        $stats = [
×
NEW
60
            'timestamp' => date('Y-m-d H:i:s'),
×
NEW
61
            'config'    => [
×
NEW
62
                'log_performance'   => $config->logPerformance,
×
NEW
63
                'retry_strategy'    => $config->retryBackoffStrategy,
×
NEW
64
                'job_timeout'       => $config->jobTimeout,
×
NEW
65
                'dead_letter_queue' => $config->deadLetterQueue ?? 'disabled',
×
NEW
66
                'batch_size'        => $config->batchSize,
×
NEW
67
            ],
×
NEW
68
            'queues' => [],
×
NEW
69
        ];
×
70

71
        // Get queue statistics
NEW
72
        $queues = is_array($config->queues) ? $config->queues : explode(',', $config->queues);
×
73

NEW
74
        foreach ($queues as $queue) {
×
NEW
75
            $queue = trim($queue);
×
76

NEW
77
            if ($specificQueue && $queue !== $specificQueue) {
×
NEW
78
                continue;
×
79
            }
80

NEW
81
            $queueStats = [
×
NEW
82
                'name'    => $queue,
×
NEW
83
                'pending' => $queueModel->where('queue', $queue)
×
NEW
84
                    ->where('status', 'pending')
×
NEW
85
                    ->countAllResults(false),
×
NEW
86
                'processing' => $queueModel->where('queue', $queue)
×
NEW
87
                    ->where('status', 'processing')
×
NEW
88
                    ->countAllResults(false),
×
NEW
89
                'completed' => $queueModel->where('queue', $queue)
×
NEW
90
                    ->where('status', 'completed')
×
NEW
91
                    ->countAllResults(false),
×
NEW
92
                'failed' => $queueModel->where('queue', $queue)
×
NEW
93
                    ->where('status', 'failed')
×
NEW
94
                    ->countAllResults(false),
×
NEW
95
            ];
×
96

97
            // Rate limit usage
NEW
98
            $rateLimit = $config->queueRateLimits[$queue] ?? 0;
×
NEW
99
            if ($rateLimit > 0) {
×
NEW
100
                $queueStats['rate_limit'] = [
×
NEW
101
                    'max_per_minute' => $rateLimit,
×
NEW
102
                    'current_usage'  => $rateLimiter->getUsage($queue),
×
NEW
103
                ];
×
104
            }
105

NEW
106
            $stats['queues'][$queue] = $queueStats;
×
107
        }
108

109
        // Job execution stats (last 24 hours)
NEW
110
        if ($config->logPerformance && $logModel) {
×
NEW
111
            $yesterday = date('Y-m-d H:i:s', strtotime('-24 hours'));
×
112

NEW
113
            $stats['last_24h'] = [
×
NEW
114
                'total_executions' => $logModel->where('created_at >=', $yesterday)->countAllResults(false),
×
NEW
115
                'successes'        => $logModel->where('created_at >=', $yesterday)
×
NEW
116
                    ->where('error', null)
×
NEW
117
                    ->countAllResults(false),
×
NEW
118
                'failures' => $logModel->where('created_at >=', $yesterday)
×
NEW
119
                    ->where('error !=', null)
×
NEW
120
                    ->countAllResults(false),
×
NEW
121
            ];
×
122

123
            // Average processing time
NEW
124
            $avgTime = $logModel->selectAvg('duration')
×
NEW
125
                ->where('created_at >=', $yesterday)
×
NEW
126
                ->get()
×
NEW
127
                ->getRow();
×
128

NEW
129
            $stats['last_24h']['avg_duration'] = $avgTime->duration ?? 0;
×
130
        }
131

NEW
132
        return $stats;
×
133
    }
134

135
    private function displayStats(array $stats): void
136
    {
NEW
137
        CLI::newLine();
×
NEW
138
        CLI::write('╔════════════════════════════════════════════════╗', 'cyan');
×
NEW
139
        CLI::write('║         Jobs System Health Check               ║', 'cyan');
×
NEW
140
        CLI::write('╚════════════════════════════════════════════════╝', 'cyan');
×
NEW
141
        CLI::newLine();
×
142

NEW
143
        CLI::write('Timestamp: ' . $stats['timestamp'], 'yellow');
×
NEW
144
        CLI::newLine();
×
145

146
        // Config
NEW
147
        CLI::write('Configuration:', 'green');
×
NEW
148
        CLI::write('  Retry Strategy: ' . $stats['config']['retry_strategy']);
×
NEW
149
        CLI::write('  Job Timeout: ' . $stats['config']['job_timeout'] . 's');
×
NEW
150
        CLI::write('  Dead Letter Queue: ' . $stats['config']['dead_letter_queue']);
×
NEW
151
        CLI::write('  Batch Size: ' . $stats['config']['batch_size']);
×
NEW
152
        CLI::newLine();
×
153

154
        // Queues
NEW
155
        CLI::write('Queue Status:', 'green');
×
156

NEW
157
        foreach ($stats['queues'] as $name => $queueStats) {
×
NEW
158
            CLI::write("  [{$name}]", 'yellow');
×
NEW
159
            CLI::write("    Pending: {$queueStats['pending']}");
×
NEW
160
            CLI::write("    Processing: {$queueStats['processing']}");
×
NEW
161
            CLI::write("    Completed: {$queueStats['completed']}");
×
NEW
162
            CLI::write("    Failed: {$queueStats['failed']}");
×
163

NEW
164
            if (isset($queueStats['rate_limit'])) {
×
NEW
165
                $rl = $queueStats['rate_limit'];
×
NEW
166
                CLI::write("    Rate Limit: {$rl['current_usage']}/{$rl['max_per_minute']} per minute");
×
167
            }
NEW
168
            CLI::newLine();
×
169
        }
170

171
        // Last 24h stats
NEW
172
        if (isset($stats['last_24h'])) {
×
NEW
173
            CLI::write('Last 24 Hours:', 'green');
×
NEW
174
            CLI::write('  Total Executions: ' . $stats['last_24h']['total_executions']);
×
NEW
175
            CLI::write('  Successes: ' . $stats['last_24h']['successes'], 'green');
×
NEW
176
            CLI::write('  Failures: ' . $stats['last_24h']['failures'], 'red');
×
NEW
177
            CLI::write('  Avg Duration: ' . round($stats['last_24h']['avg_duration'], 2) . 's');
×
178
        }
179

NEW
180
        CLI::newLine();
×
181
    }
182
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc