diff --git a/src/Jenssegers/Mongodb/Queue/MongoQueue.php b/src/Jenssegers/Mongodb/Queue/MongoQueue.php index 369ef6b72..fd313977e 100644 --- a/src/Jenssegers/Mongodb/Queue/MongoQueue.php +++ b/src/Jenssegers/Mongodb/Queue/MongoQueue.php @@ -4,6 +4,7 @@ use Carbon\Carbon; use Illuminate\Queue\DatabaseQueue; +use Illuminate\Queue\Jobs\DatabaseJob; use Jenssegers\Mongodb\Connection; use MongoDB\Operation\FindOneAndUpdate; @@ -131,4 +132,41 @@ public function deleteReserved($queue, $id) { $this->database->collection($this->table)->where('_id', $id)->delete(); } + + /** + * @param string $queue + * @param DatabaseJob $job + * @param int $delay + * + * @return object|null + */ + public function release($queue, $job, $delay) + { + $result = $this->database->getCollection($this->table)->findOneAndUpdate( + [ + '_id' => $job->getJobId(), + ], + [ + '$set' => [ + 'queue' => $queue, + 'reserved' => 0, + 'reserved_at' => null, + 'available_at' => Carbon::now()->addRealSeconds($delay)->getTimestamp(), + ], + ], + [ + 'returnDocument' => FindOneAndUpdate::RETURN_DOCUMENT_AFTER + ] + ); + + return $result->_id ?? null; + } + + /** + * @inheritDoc + */ + public function deleteAndRelease($queue, $job, $delay) + { + $this->release($queue, $job, $delay); + } } diff --git a/tests/QueueTest.php b/tests/QueueTest.php index 5b07c9492..953dce3af 100644 --- a/tests/QueueTest.php +++ b/tests/QueueTest.php @@ -4,6 +4,7 @@ use Carbon\Carbon; use Illuminate\Support\Str; use Jenssegers\Mongodb\Queue\Failed\MongoFailedJobProvider; +use Jenssegers\Mongodb\Queue\MongoQueue; class QueueTest extends TestCase { @@ -103,4 +104,46 @@ public function testIncrementAttempts(): void $this->assertCount(1, $others_jobs); $this->assertEquals(0, $others_jobs[0]['attempts']); } + + public function testQueueJobRelease(): void + { + $queue = 'test_queue'; + $released_to_queue = 'test_queue'; + $delay = 1234; + + $id = Queue::push('test', [], $queue); + $job = Queue::pop($queue); + + $released_job_id = Queue::release($released_to_queue, $job, $delay); + $this->assertEquals($id, $released_job_id); + + $result = Queue::getDatabase() + ->table(Config::get('queue.connections.database.table')) + ->where('_id', $released_job_id) + ->first(); + + $this->assertEquals($released_to_queue, $result['queue']); + $this->assertEquals(1, $result['attempts']); + $this->assertEquals(0, $result['reserved']); + $this->assertNull($result['reserved_at']); + $this->assertEquals( + Carbon::now()->addRealSeconds($delay)->getTimestamp(), + $result['available_at'] + ); + $this->assertEquals(Carbon::now()->getTimestamp(), $result['created_at']); + $this->assertEquals($job->getRawBody(), $result['payload']); + } + + public function testQueueJobDeleteAndRelease(): void + { + $mock = Mockery::mock(MongoQueue::class)->makePartial(); + + $queue = 'queue_name'; + $job = ''; + $delay = 1234; + + //Skip parent method (uses transactions) - call release() method + $mock->shouldReceive('release')->once()->with($queue, $job, $delay); + $mock->deleteAndRelease($queue, $job, $delay); + } }