Configuration
The package reads its settings from Daycry\Jobs\Config\Jobs (you may publish / copy to your app namespace to customize). Below is an overview of the most relevant options.
Core
Property |
Type |
Description |
|---|---|---|
|
array |
Mapping of job handler keys (e.g. |
|
string |
array |
|
string |
Active queue backend key referencing |
|
array |
Map of worker key => queue implementation class. Instances cached by |
|
bool |
Enable/disable structured execution logging. |
|
string |
Logging driver key ( |
|
array |
Map logging driver key => handler class. |
|
string |
Directory for file logs (one JSON file per job name). |
|
int |
Prune old records (database) or lines (file) beyond this count (file handler may ignore if not implemented). |
|
array |
List of payload/output/error keys (case-insensitive) to mask recursively. |
|
?int |
Truncate output & error string length (null = unlimited). |
Security & Performance
Property |
Type |
Default |
Description |
|---|---|---|---|
|
array |
|
Whitelist for |
|
array |
|
Per-queue rate limits (jobs/minute). Format: |
|
?string |
|
Queue name for permanently failed jobs. When |
|
int |
|
Maximum execution time per job in seconds. 0 = disabled. Uses |
|
int |
|
Reserved for future batch processing feature. Currently unused. |
Worker behaviour
Property |
Type |
Default |
Description |
|---|---|---|---|
|
int |
|
Seconds to sleep between polling cycles when no job is available. Skipped automatically when |
|
bool |
|
Opt in to blocking fetch on backends that support it (Redis |
|
int |
|
Seconds to wait per blocking fetch (also acts as the upper bound for graceful shutdown latency). |
|
int |
|
Visibility timeout (seconds) used by |
|
int |
|
Lock timeout (seconds) requested when peek-locking Service Bus messages. Should be ≥ the maximum job runtime; otherwise the broker may redeliver mid-execution. |
|
int |
|
Consecutive backend failures before the circuit opens. |
|
int |
|
Seconds the circuit stays open before the worker retries the backend. |
Retry / Backoff
Property |
Type |
Notes |
|---|---|---|
|
string |
|
|
int |
Base delay (seconds) for first retry. |
|
float |
Exponential factor: |
|
int |
Upper cap on any computed delay. |
|
bool |
Add +/- up to 15% random jitter. |
Timeout
Property |
Type |
Description |
|---|---|---|
|
?int |
Global timeout seconds for jobs lacking explicit timeout. (Enforcement dependent on execution wrapper.) |
Backend Specific
Database
Property |
Path |
Description |
|---|---|---|
|
|
Connection group + table for queue storage. |
Redis
Relies on ext-redis and host/port taken from environment (e.g. REDIS_HOST, REDIS_PORT).
Beanstalk
Key |
Default |
|---|---|
|
127.0.0.1 |
|
11300 |
Azure Service Bus
Key |
Description |
|---|---|
|
Full queue endpoint. |
|
SAS key name. |
|
SAS key value. |
Sensitive Data Masking
The effective keys are the union of internal defaults (password, token, secret, authorization, api_key) plus any configured in $sensitiveKeys and those appended dynamically at runtime. Matching is case-insensitive and recursive across arrays/objects. Values are replaced with ***.
Enhanced Token Pattern Detection (v1.0.3+)
In addition to key-based masking, the logger automatically detects and masks:
JWT Tokens: Format
xxx.yyy.zzz→***JWT_TOKEN***API Keys: known provider prefixes (
sk_(live|test)_…,pk_(live|test)_…,AKIA…(AWS),gh[pousr]_…(GitHub PATs),xox[abprs]-…(Slack)) or opaque alphanumeric strings of 40 characters or more →***API_KEY***. The previous “32+ chars” rule was tightened in v1.0.3 so 32-character UUIDs and SHA-1 hex digests are no longer false positives.Bearer Tokens:
Bearer <token>→Bearer ***TOKEN***
Recursion is bounded by MAX_MASK_DEPTH = 10; payloads nested deeper than that are replaced by [truncated:max-depth] so adversarial deep arrays/objects cannot cause a stack overflow.
This pattern-based detection works independently of key names, providing defense-in-depth for leaked credentials.
Security Features
Shell Command Whitelisting
Restrict which shell commands can be executed by ShellJob. Recommended in v1.1+: use absolute paths so /tmp/echo cannot impersonate a whitelisted /usr/bin/echo:
// Recommended (v1.1+): absolute paths matched via realpath()
public array $allowedShellCommands = ['/usr/bin/ls', '/usr/bin/grep', '/usr/bin/cat'];
// Legacy (deprecated, still works with a warning log)
public array $allowedShellCommands = ['ls', 'grep', 'cat'];
Empty array (default): All commands allowed (backward compatible).
Entries with a path separator (
/or\\) are resolved withrealpath()and compared against the resolved candidate./tmp/echois rejected even if the whitelist contains/usr/bin/echo.Bare names fall back to the legacy
basename()match and emit a deprecation warning. This mode is removed in v2.0.Throws
JobException::forShellCommandNotAllowed()on violation.
Rate Limiting
Prevents queue overload with per-queue limits:
public array $queueRateLimits = [
'high_priority' => 100, // Max 100 jobs/minute
'default' => 50, // Max 50 jobs/minute
];
Implementation:
Cache-based token bucket algorithm
Worker skips processing when limit exceeded
Use
RateLimiterclass for programmatic access:$limiter = new \Daycry\Jobs\Libraries\RateLimiter(); if ($limiter->allow('default', 50)) { // Process job }
Dead Letter Queue (DLQ)
Automatic routing of permanently failed jobs for forensic analysis:
public ?string $deadLetterQueue = 'failed_jobs';
Behavior (v1.0.3+):
Jobs exceeding max retries are moved to the DLQ before being cleared from the origin queue, so a DLQ failure does not lose the message.
DeadLetterQueue::store()returnsbool—falsemeans the DLQ was unconfigured or the underlying push failed;RequeueHelperthen emits thejobs_dlq_failedmetric so operators can alert on it.Without
$deadLetterQueue, permanently failed jobs are still removed from the origin (otherwise some backends — Redis processing list, ServiceBus settle — would loop forever) and acriticallog entry is recorded.Metadata added when stored:
dlq_reason,dlq_timestamp,dlq_attempts,original_queue.Retrieve stats:
$dlq->getStats().
Job Timeout Protection
Hard enforcement of maximum execution time:
public int $jobTimeout = 300; // 5 minutes
0 = disabled (backward compatible)
Uses
pcntl_alarm()for signal-based timeout (kills runaway processes)Fallback to time check if
pcntlextension unavailableThrows
JobException::forJobTimeout()when exceeded
Queue Management
QueueManager (Centralized Registry)
Access queue backends via singleton:
use Daycry\Jobs\Libraries\QueueManager;
// Get default worker
$queue = QueueManager::instance()->getDefault();
// Get specific worker by name
$queue = QueueManager::instance()->get('redis');
// List all configured workers
$workers = QueueManager::instance()->list();
PayloadSerializer (Schema Versioning)
All queues use centralized serialization:
use Daycry\Jobs\Libraries\JsonPayloadSerializer;
$serializer = new JsonPayloadSerializer(schemaVersion: 2);
$queue->setSerializer($serializer);
InstrumentedQueueDecorator (Metrics)
Wrap any queue for transparent metrics:
use Daycry\Jobs\Libraries\InstrumentedQueueDecorator;
use Daycry\Jobs\Metrics\InMemoryMetricsCollector;
$metrics = new InMemoryMetricsCollector();
$instrumented = new InstrumentedQueueDecorator(
queue: $queue,
metrics: $metrics,
backendName: 'redis'
);
// Tracks: enqueue_total, fetch_total, ack_total, nack_total, durations
Publishing / Overriding
Copy src/Config/Jobs.php into app/Config/Jobs.php and modify. CodeIgniter’s service locator will favor the application namespace.
Minimal Example
$cfg = config('Jobs');
$cfg->queues = 'default,mail';
$cfg->worker = 'redis';
$cfg->logPerformance = true;
$cfg->sensitiveKeys[] = 'access_token';
$cfg->retryBackoffStrategy = 'exponential';
$cfg->retryBackoffBase = 3;
$cfg->retryBackoffMultiplier = 2.5;
$cfg->retryBackoffMax = 180;