Skip to content

Commit

Permalink
Return More Information from Consumer::once
Browse files Browse the repository at this point in the history
Via a result object. this is to make some telemetry stuff easier.
  • Loading branch information
chrisguitarguy committed Jul 11, 2024
1 parent 508a72c commit 46b0ab5
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 18 deletions.
5 changes: 2 additions & 3 deletions src/Consumer.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,9 @@ public function run(string $queueName, MessageLifecycle $lifecycle=null) : int;
* stop execption indicating a graceful stop is necessary
* @throws Exception\DriverError|Exception if anything goes wrong with the
* underlying driver itself.
* @return boolean|null True if the a job was execute successfully. Null if
* no job was executed. See the logs.
* @return OnceResult|null a result object if a message was recieved and handled, null otherwise
*/
public function once(string $queueName, MessageLifecycle $lifecycle=null) : ?bool;
public function once(string $queueName, MessageLifecycle $lifecycle=null) : ?OnceResult;

/**
* Gracefully stop the consumer with the given exit code.
Expand Down
4 changes: 2 additions & 2 deletions src/DefaultConsumer.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public function __construct(
/**
* {@inheritdoc}
*/
public function once(string $queueName, MessageLifecycle $lifecycle=null) : ?bool
public function once(string $queueName, MessageLifecycle $lifecycle=null) : ?OnceResult
{
$envelope = $this->driver->dequeue($queueName);
if (!$envelope) {
Expand All @@ -90,7 +90,7 @@ public function once(string $queueName, MessageLifecycle $lifecycle=null) : ?boo
$lifecycle->failed($message, $this);
}

return $succeeded;
return new OnceResult($succeeded, $willRetry, $message);
}

/**
Expand Down
34 changes: 34 additions & 0 deletions src/OnceResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php declare(strict_types=1);

/**
* This file is part of PMG\Queue
*
* Copyright (c) PMG <https://www.pmg.com>
*
* For full copyright information see the LICENSE file distributed
* with this source code.
*
* @license http://opensource.org/licenses/Apache-2.0 Apache-2.0
*/

namespace PMG\Queue;

final readonly class OnceResult
{
public function __construct(
/**
* Whether or not the `once` method ran successfully -- eg a message
* was handled without an error.
*/
public bool $successful,
/**
* True if the message has been put back in the queue to retry
*/
public bool $retrying,
/**
* The message that was processed
*/
public object $message,
) {
}
}
8 changes: 4 additions & 4 deletions test/unit/AbstractConsumerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function testRunConsumesMessagesUntilConsumerIsStopped()
->method('once')
->with(self::Q)
->will($this->onConsecutiveCalls(
true, // successful :tada:
new OnceResult(true, false, $this->message),
$this->throwException(new Exception\SimpleMustStop('oops', 1))
));

Expand All @@ -44,7 +44,7 @@ public function testRunStopsWhenADriverErrorIsThrown()
->method('once')
->with(self::Q)
->will($this->onConsecutiveCalls(
true, // successful :tada:
new OnceResult(true, false, $this->message),
$this->throwException(new Exception\SerializationError('broke'))
));

Expand All @@ -65,7 +65,7 @@ public function testRunStopsWhenAThrowableisCaught()
->method('once')
->with(self::Q)
->will($this->onConsecutiveCalls(
true, // successful :tada:
new OnceResult(true, false, $this->message),
$this->throwException(new \Error('oops'))
));

Expand Down Expand Up @@ -100,7 +100,7 @@ public function testRunPassesGivenMessageLifecycleToOnce()
->method('once')
->with(self::Q, $this->identicalTo($lifecycle))
->will($this->onConsecutiveCalls(
true, // successful :tada:
new OnceResult(true, false, $this->message),
$this->throwException(new Exception\SimpleMustStop('oops', 1))
));

Expand Down
39 changes: 30 additions & 9 deletions test/unit/DefaultConsumerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ public function testOnceExecutesTheMessageAndAcknowledgesIt()
->with($this->identicalTo($this->message))
->willReturn(self::promise(true));

$this->assertTrue($this->consumer->once(self::Q));
$result = $this->consumer->once(self::Q);

$this->assertTrue($result->successful);
$this->assertFalse($result->retrying);
$this->assertSame($this->message, $result->message);
}

public function testPlainObjectMessagesCanBeHandled()
Expand All @@ -87,7 +91,11 @@ public function testPlainObjectMessagesCanBeHandled()
->with($this->identicalTo($message))
->willReturn(self::promise(true));

$this->assertTrue($this->consumer->once(self::Q));
$result = $this->consumer->once(self::Q);

$this->assertTrue($result->successful);
$this->assertFalse($result->retrying);
$this->assertSame($message, $result->message);
}

public function testOnceWithAFailedMessageAndValidRetryPutsTheMessageBackInTheQueue()
Expand All @@ -102,7 +110,11 @@ public function testOnceWithAFailedMessageAndValidRetryPutsTheMessageBackInTheQu
->with($this->identicalTo($this->message))
->willReturn(self::promise(false));

$this->assertFalse($this->consumer->once(self::Q));
$result = $this->consumer->once(self::Q);

$this->assertFalse($result->successful);
$this->assertTrue($result->retrying);
$this->assertSame($this->message, $result->message);
}

public function testFailedMessageThatCannotBeRetriedIsNotPutBackInTheQueue()
Expand All @@ -118,7 +130,11 @@ public function testFailedMessageThatCannotBeRetriedIsNotPutBackInTheQueue()
->with($this->identicalTo($this->message))
->willReturn(self::promise(false));

$this->assertFalse($this->consumer->once(self::Q));
$result = $this->consumer->once(self::Q);

$this->assertFalse($result->successful);
$this->assertFalse($result->retrying);
$this->assertSame($this->message, $result->message);
}

public function testOnceWithAExceptionThrownFromHandlerAndValidRetryRetriesJobAndThrows()
Expand All @@ -133,9 +149,10 @@ public function testOnceWithAExceptionThrownFromHandlerAndValidRetryRetriesJobAn
->with($this->identicalTo($this->message))
->willThrowException(new \Exception('oops'));

$this->assertFalse($this->consumer->once(self::Q));
$messages = $this->logger->getMessages(LogLevel::CRITICAL);
$result = $this->consumer->once(self::Q);

$this->assertFalse($result->successful);
$messages = $this->logger->getMessages(LogLevel::CRITICAL);
$this->assertCount(1, $messages);
$this->assertStringContainsString('oops', $messages[0]);
$this->assertStringContainsString('TestMessage', $messages[0]);
Expand Down Expand Up @@ -168,6 +185,10 @@ public function testFailureWithShouldReleaseReleasesMessageBackIntoDriver()
->willThrowException(new Exception\ForkedProcessCancelled('oops'));

$result = $this->consumer->once(self::Q);

$this->assertFalse($result->successful);
$this->assertTrue($result->retrying);
$this->assertSame($this->message, $result->message);
}

/**
Expand All @@ -194,7 +215,7 @@ public function testLifecycleOfSuccessfulMessageCallsExpectedLifecycleMethods()

$result = $this->consumer->once(self::Q, $lifecycle);

$this->assertTrue($result);
$this->assertTrue($result->successful);
}

/**
Expand Down Expand Up @@ -224,7 +245,7 @@ public function testLifecycleOnFailedMessageCallsExpectedLifecycleMethods()

$result = $this->consumer->once(self::Q, $lifecycle);

$this->assertFalse($result);
$this->assertFalse($result->successful);
}

/**
Expand Down Expand Up @@ -252,7 +273,7 @@ public function testLifecycleOnRetryingMessageCallsExpectedLifecycleMethods()

$result = $this->consumer->once(self::Q, $lifecycle);

$this->assertFalse($result);
$this->assertFalse($result->successful);
}

/**
Expand Down
1 change: 1 addition & 0 deletions test/unit/Handler/PcntlForkingHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* This uses `CallableHandler` simply because I'm not sure how phpunit mock objects
* behave in forked processes.
*
* @group pcntl
* @requires extension pcntl
*/
class PcntlForkingHandlerTest extends \PMG\Queue\UnitTestCase
Expand Down

0 comments on commit 46b0ab5

Please sign in to comment.