Migrating from v1 to v2
Status (v1.2 release): the v2 namespace
Daycry\Jobs\V2\ships alongside the v1 API. Existing code keeps working unchanged; v2 is opt-in. The legacy mutableJobbuilder and the splitQueueInterface/WorkerInterfacewill be deprecated in v1.3 and removed in a future major release.
This document describes the gradual adoption path so a codebase can migrate file-by-file without a big-bang rewrite.
What changes in v2
Concern |
v1 |
v2 |
|---|---|---|
Job description |
Mutable |
Immutable |
Queue interface |
Two coupled interfaces: |
Single |
In-flight tracking |
Backend instance member |
Explicit |
Handler payload |
|
|
Service locator |
|
DI via constructor (with |
What does NOT change in v1.x
Cron scheduling, retries, callbacks, masking, metrics, ServiceBus peek-lock and Redis reliable queue (added in v1.1) all keep their existing APIs.
Existing handlers, schedulers, and
php spark jobs:queue:runinvocations work as before.Config\Jobs.phpis untouched:$jobs,$workers,$worker,$queues, etc. stay the same.
Step-by-step adoption
1. Wrap an existing backend as v2
The fastest way to start using the v2 contract without rewriting any backend:
use Daycry\Jobs\Libraries\QueueManager;
use Daycry\Jobs\V2\JobDefinition;
use Daycry\Jobs\V2\Queues\LegacyWorkerAdapter;
$legacy = QueueManager::instance()->getDefault(); // your existing redis/database/etc.
$adapter = new LegacyWorkerAdapter($legacy, 'redis', 300); // 300s lease
$definition = new JobDefinition(handler: 'command', payload: 'jobs:test');
$id = $adapter->enqueue($definition->withQueue('reports')->withMaxRetries(3));
// Worker side
while ($lease = $adapter->fetch('reports')) {
try {
// ... process $lease->envelope->payload ...
$adapter->ack($lease);
} catch (\Throwable) {
$adapter->nack($lease);
}
}
The adapter holds at most ONE in-flight lease per instance (legacy WorkerInterface state limitation). Use one adapter per worker and you preserve the existing semantics for free.
3. Use JobDefinition::fromLegacyJob() during the transition
When mixing v1 and v2 sites:
$legacyJob = (new \Daycry\Jobs\Job(job: 'command', payload: 'x'))
->named('legacy_demo')
->setQueue('reports')
->maxRetries(3);
$definition = JobDefinition::fromLegacyJob($legacyJob); // immutable snapshot
$adapter->enqueue($definition);
This gives you a single canonical value object even when older code still produces a
mutable Job. Once every call site has migrated to building JobDefinition directly, the
legacy bridge can be removed.
4. Replace service-locator calls in your handlers (v1.2)
The notification logic was extracted to Daycry\Jobs\Notifications\NotificationService so
you can mock the email transport in tests:
use Daycry\Jobs\Notifications\NotificationService;
$svc = new NotificationService(
email: $mockEmail,
parser: $mockParser,
from: 'jobs@example.com',
fromName: 'Jobs',
to: 'oncall@example.com',
view: 'Daycry\Jobs\Views\email_notification',
timezone: 'UTC',
);
// Inject explicitly to bypass the service locator entirely:
$result = $job->notify($executionResult, $svc);
JobLogger::__construct accepts an optional handler and a deterministic execution id for
the same testing reason.
Roadmap to native v2 backends
The current LegacyWorkerAdapter is a stop-gap. Future minor releases will ship native v2
implementations of each backend, expose their delay-aware nack semantics, and lift the
“one in-flight lease per adapter” restriction. Once those are available, integrators can
swap the adapter for the native backend without changing call sites:
// future v1.3
use Daycry\Jobs\V2\Queues\RedisBackend;
$backend = new RedisBackend(/* config */);
$lease = $backend->fetch('default');
Deprecation timeline (proposed)
v1.2 (current) — v2 namespace ships; everything in v1 keeps working.
v1.3 — native v2 backend(s) for at least Redis and Database;
LegacyWorkerAdapterbecomes the recommended bridge forServiceBusQueueandBeanstalkQueueonly.v2.0 — legacy
QueueInterface/WorkerInterfaceand the mutableJobbuilder are marked@deprecated. Existing code still works through compatibility shims.v3.0 — legacy API removed. Migration path documented in the upgrade guide.
No timeline is committed beyond v1.2; the schedule above is intent-of-direction and may shift based on community uptake of the v2 API.