Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 60574c8

Browse files
committed
[dbal] Order prioritized messages by publised at date.
1 parent 6c34b77 commit 60574c8

9 files changed

+171
-52
lines changed

pkg/dbal/DbalConsumer.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ protected function convertMessage(array $dbalMessage)
186186
$message->setBody($dbalMessage['body']);
187187
$message->setPriority((int) $dbalMessage['priority']);
188188
$message->setRedelivered((bool) $dbalMessage['redelivered']);
189+
$message->setPublishedAt((int) $dbalMessage['published_at']);
189190

190191
if ($dbalMessage['headers']) {
191192
$message->setHeaders(JSON::decode($dbalMessage['headers']));

pkg/dbal/DbalMessage.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ class DbalMessage implements PsrMessage
4141
*/
4242
private $timeToLive;
4343

44+
/**
45+
* Milliseconds, for example 15186054527288.
46+
*
47+
* Could be generated by the code: (int) (microtime(true) * 10000)
48+
*
49+
* @var int
50+
*/
51+
private $publishedAt;
52+
4453
/**
4554
* @param string $body
4655
* @param array $properties
@@ -259,7 +268,7 @@ public function getTimestamp()
259268
{
260269
$value = $this->getHeader('timestamp');
261270

262-
return $value === null ? null : (int) $value;
271+
return null === $value ? null : (int) $value;
263272
}
264273

265274
/**
@@ -269,4 +278,20 @@ public function setTimestamp($timestamp)
269278
{
270279
$this->setHeader('timestamp', $timestamp);
271280
}
281+
282+
/**
283+
* @return int
284+
*/
285+
public function getPublishedAt()
286+
{
287+
return $this->publishedAt;
288+
}
289+
290+
/**
291+
* @param int $publishedAt
292+
*/
293+
public function setPublishedAt($publishedAt)
294+
{
295+
$this->publishedAt = $publishedAt;
296+
}
272297
}

pkg/dbal/DbalProducer.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function send(PsrDestination $destination, PsrMessage $message)
5454
InvalidDestinationException::assertDestinationInstanceOf($destination, DbalDestination::class);
5555
InvalidMessageException::assertMessageInstanceOf($message, DbalMessage::class);
5656

57-
if (null !== $this->priority && null === $message->getPriority()) {
57+
if (null !== $this->priority && 0 === $message->getPriority()) {
5858
$message->setPriority($this->priority);
5959
}
6060
if (null !== $this->deliveryDelay && null === $message->getDeliveryDelay()) {
@@ -81,9 +81,14 @@ public function send(PsrDestination $destination, PsrMessage $message)
8181
throw new \LogicException('The generated uuid is empty');
8282
}
8383

84+
$publishedAt = null !== $message->getPublishedAt() ?
85+
$message->getPublishedAt() :
86+
(int) (microtime(true) * 10000)
87+
;
88+
8489
$dbalMessage = [
8590
'id' => $uuid,
86-
'published_at' => (int) (microtime(true) * 10000),
91+
'published_at' => $publishedAt,
8792
'body' => $body,
8893
'headers' => JSON::encode($message->getHeaders()),
8994
'properties' => JSON::encode($message->getProperties()),

pkg/dbal/Tests/DbalConsumerTest.php

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22

33
namespace Enqueue\Dbal\Tests;
44

5-
use Doctrine\DBAL\Connection;
6-
use Doctrine\DBAL\Platforms\AbstractPlatform;
7-
use Doctrine\DBAL\Query\QueryBuilder;
8-
use Doctrine\DBAL\Statement;
95
use Enqueue\Dbal\DbalConsumer;
106
use Enqueue\Dbal\DbalContext;
117
use Enqueue\Dbal\DbalDestination;
@@ -120,45 +116,13 @@ private function createProducerMock()
120116
return $this->createMock(DbalProducer::class);
121117
}
122118

123-
/**
124-
* @return \PHPUnit_Framework_MockObject_MockObject|Connection
125-
*/
126-
private function createConnectionMock()
127-
{
128-
return $this->createMock(Connection::class);
129-
}
130-
131-
/**
132-
* @return \PHPUnit_Framework_MockObject_MockObject|Statement
133-
*/
134-
private function createStatementMock()
135-
{
136-
return $this->createMock(Statement::class);
137-
}
138-
139119
/**
140120
* @return \PHPUnit_Framework_MockObject_MockObject|DbalContext
141121
*/
142122
private function createContextMock()
143123
{
144124
return $this->createMock(DbalContext::class);
145125
}
146-
147-
/**
148-
* @return \PHPUnit_Framework_MockObject_MockObject|QueryBuilder
149-
*/
150-
private function createQueryBuilderMock()
151-
{
152-
return $this->createMock(QueryBuilder::class);
153-
}
154-
155-
/**
156-
* @return \PHPUnit_Framework_MockObject_MockObject|AbstractPlatform
157-
*/
158-
private function createPlatformMock()
159-
{
160-
return $this->createMock(AbstractPlatform::class);
161-
}
162126
}
163127

164128
class InvalidMessage implements PsrMessage

pkg/dbal/Tests/DbalMessageTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ public function testShouldSetCorrelationIdAsHeader()
4949
$this->assertSame(['correlation_id' => 'theCorrelationId'], $message->getHeaders());
5050
}
5151

52+
public function testShouldSetPublishedAtToNullInConstructor()
53+
{
54+
$message = new DbalMessage();
55+
56+
$this->assertNull($message->getPublishedAt());
57+
}
58+
5259
public function testShouldSetMessageIdAsHeader()
5360
{
5461
$message = new DbalMessage();
@@ -72,4 +79,13 @@ public function testShouldSetReplyToAsHeader()
7279

7380
$this->assertSame(['reply_to' => 'theReply'], $message->getHeaders());
7481
}
82+
83+
public function testShouldAllowGetPreviouslySetPublishedAtTime()
84+
{
85+
$message = new DbalMessage();
86+
87+
$message->setPublishedAt(123);
88+
89+
$this->assertSame(123, $message->getPublishedAt());
90+
}
7591
}

pkg/dbal/Tests/DbalProducerTest.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace Enqueue\Dbal\Tests;
44

5-
use Doctrine\DBAL\Connection;
65
use Enqueue\Dbal\DbalContext;
76
use Enqueue\Dbal\DbalDestination;
87
use Enqueue\Dbal\DbalMessage;
@@ -60,14 +59,6 @@ private function createContextMock()
6059
{
6160
return $this->createMock(DbalContext::class);
6261
}
63-
64-
/**
65-
* @return \PHPUnit_Framework_MockObject_MockObject|Connection
66-
*/
67-
private function createConnectionMock()
68-
{
69-
return $this->createMock(Connection::class);
70-
}
7162
}
7263

7364
class NotSupportedDestination1 implements PsrDestination
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
namespace Enqueue\Dbal\Tests\Spec;
4+
5+
use Enqueue\Dbal\DbalContext;
6+
use Enqueue\Dbal\DbalMessage;
7+
use PHPUnit\Framework\TestCase;
8+
9+
/**
10+
* @group functional
11+
*/
12+
class DbalConsumerTest extends TestCase
13+
{
14+
use CreateDbalContextTrait;
15+
16+
/**
17+
* @var DbalContext
18+
*/
19+
private $context;
20+
21+
public function setUp()
22+
{
23+
$this->context = $this->createDbalContext();
24+
}
25+
26+
protected function tearDown()
27+
{
28+
if ($this->context) {
29+
$this->context->close();
30+
}
31+
32+
parent::tearDown();
33+
}
34+
35+
public function testShouldSetPublishedAtDateToReceivedMessage()
36+
{
37+
$context = $this->context;
38+
$queue = $context->createQueue(__METHOD__);
39+
40+
$consumer = $context->createConsumer($queue);
41+
42+
// guard
43+
$this->assertNull($consumer->receiveNoWait());
44+
45+
$time = (int) (microtime(true) * 10000);
46+
47+
$expectedBody = __CLASS__.$time;
48+
49+
$producer = $context->createProducer();
50+
51+
$message = $context->createMessage($expectedBody);
52+
$message->setPublishedAt($time);
53+
$producer->send($queue, $message);
54+
55+
$message = $consumer->receive(8000); // 8 sec
56+
57+
$this->assertInstanceOf(DbalMessage::class, $message);
58+
$consumer->acknowledge($message);
59+
$this->assertSame($expectedBody, $message->getBody());
60+
$this->assertSame($time, $message->getPublishedAt());
61+
}
62+
63+
public function testShouldOrderMessagesWithSamePriorityByPublishedAtDate()
64+
{
65+
$context = $this->context;
66+
$queue = $context->createQueue(__METHOD__);
67+
68+
$consumer = $context->createConsumer($queue);
69+
70+
// guard
71+
$this->assertNull($consumer->receiveNoWait());
72+
73+
$time = (int) (microtime(true) * 10000);
74+
$olderTime = $time - 10000;
75+
76+
$expectedPriority5Body = __CLASS__.'_priority5_'.$time;
77+
$expectedPriority5BodyOlderTime = __CLASS__.'_priority5_'.$olderTime;
78+
79+
$producer = $context->createProducer();
80+
81+
$message = $context->createMessage($expectedPriority5Body);
82+
$message->setPriority(5);
83+
$message->setPublishedAt($time);
84+
$producer->send($queue, $message);
85+
86+
$message = $context->createMessage($expectedPriority5BodyOlderTime);
87+
$message->setPriority(5);
88+
$message->setPublishedAt($olderTime);
89+
$producer->send($queue, $message);
90+
91+
$message = $consumer->receive(8000); // 8 sec
92+
93+
$this->assertInstanceOf(DbalMessage::class, $message);
94+
$consumer->acknowledge($message);
95+
$this->assertSame($expectedPriority5BodyOlderTime, $message->getBody());
96+
97+
$message = $consumer->receive(8000); // 8 sec
98+
99+
$this->assertInstanceOf(DbalMessage::class, $message);
100+
$consumer->acknowledge($message);
101+
$this->assertSame($expectedPriority5Body, $message->getBody());
102+
}
103+
}

pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Enqueue\Dbal\Tests\Spec;
44

5+
use Enqueue\Dbal\DbalContext;
56
use Enqueue\Dbal\DbalMessage;
67
use Interop\Queue\PsrContext;
78
use Interop\Queue\Spec\SendAndReceivePriorityMessagesFromQueueSpec;
@@ -13,6 +14,15 @@ class DbalSendAndReceivePriorityMessagesFromQueueTest extends SendAndReceivePrio
1314
{
1415
use CreateDbalContextTrait;
1516

17+
private $publishedAt;
18+
19+
public function setUp()
20+
{
21+
parent::setUp();
22+
23+
$this->publishedAt = (int) (microtime(true) * 10000);
24+
}
25+
1626
/**
1727
* @return PsrContext
1828
*/
@@ -24,13 +34,17 @@ protected function createContext()
2434
/**
2535
* {@inheritdoc}
2636
*
37+
* @param DbalContext $context
38+
*
2739
* @return DbalMessage
2840
*/
29-
protected function createMessage(PsrContext $context, $priority)
41+
protected function createMessage(PsrContext $context, $body)
3042
{
3143
/** @var DbalMessage $message */
32-
$message = $context->createMessage('priority'.$priority);
33-
$message->setPriority($priority);
44+
$message = parent::createMessage($context, $body);
45+
46+
// in order to test priorities correctly we have to make sure the messages were sent in the same time.
47+
$message->setPublishedAt($this->publishedAt);
3448

3549
return $message;
3650
}

pkg/dbal/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"enqueue/test": "^0.8@dev",
1616
"enqueue/enqueue": "^0.8@dev",
1717
"enqueue/null": "^0.8@dev",
18-
"queue-interop/queue-spec": "^0.5.4@dev",
18+
"queue-interop/queue-spec": "^0.5.5@dev",
1919
"symfony/dependency-injection": "^2.8|^3|^4",
2020
"symfony/config": "^2.8|^3|^4"
2121
},

0 commit comments

Comments
 (0)