@@ -36,6 +36,7 @@ class Connection
36
36
37
37
private $ connection ;
38
38
private $ stream ;
39
+ private $ queue ;
39
40
private $ group ;
40
41
private $ consumer ;
41
42
private $ autoSetup ;
@@ -57,6 +58,7 @@ public function __construct(array $configuration, array $connectionCredentials =
57
58
}
58
59
59
60
$ this ->stream = $ configuration ['stream ' ] ?? self ::DEFAULT_OPTIONS ['stream ' ];
61
+ $ this ->queue = $ this ->stream .'_queue ' ;
60
62
$ this ->group = $ configuration ['group ' ] ?? self ::DEFAULT_OPTIONS ['group ' ];
61
63
$ this ->consumer = $ configuration ['consumer ' ] ?? self ::DEFAULT_OPTIONS ['consumer ' ];
62
64
$ this ->autoSetup = $ configuration ['auto_setup ' ] ?? self ::DEFAULT_OPTIONS ['auto_setup ' ];
@@ -112,6 +114,18 @@ public function get(): ?array
112
114
$ this ->setup ();
113
115
}
114
116
117
+ $ queuedMessageCount = $ this ->connection ->zcount ($ this ->queue , 0 , time ());
118
+
119
+ if ($ queuedMessageCount ) {
120
+ foreach ($ this ->connection ->zpopmin ($ this ->queue , $ queuedMessageCount ) as $ queuedMessage => $ time ) {
121
+ $ queuedMessage = json_encode ($ queuedMessage , true );
122
+ // if a futured placed message is actually popped because of a race condition with
123
+ // another running message consumer, the message is readded to the queue by add function
124
+ // else its just added stream and will be available for all stream consumers
125
+ $ this ->add ($ queuedMessage ['body ' ], $ queuedMessage ['headers ' ], (time () - $ time ) * 1000 );
126
+ }
127
+ }
128
+
115
129
$ messageId = '> ' ; // will receive new messages
116
130
117
131
if ($ this ->couldHavePendingMessages ) {
@@ -182,22 +196,27 @@ public function reject(string $id): void
182
196
}
183
197
}
184
198
185
- public function add (string $ body , array $ headers ): void
199
+ /**
200
+ * @param int $delay The delay in milliseconds
201
+ */
202
+ public function add (string $ body , array $ headers , int $ delay = 0 ): void
186
203
{
187
204
if ($ this ->autoSetup ) {
188
205
$ this ->setup ();
189
206
}
190
207
191
208
$ e = null ;
192
209
try {
193
- if ( $ this -> maxEntries ) {
194
- $ added = $ this -> connection -> xadd ( $ this -> stream , ' * ' , [ ' message ' => json_encode (
195
- [ ' body ' => $ body , ' headers ' => $ headers ]
196
- )], $ this ->maxEntries , true );
210
+ $ message = json_encode ([ ' body ' => $ body , ' headers ' => $ headers ]);
211
+
212
+ if ( $ delay > 0 ) { // the delay could be smaller 0 in a queued message
213
+ $ added = $ this ->connection -> zadd ( $ this -> queue , [ ' NX ' ], time () + ( $ delay / 1000 ), $ message );
197
214
} else {
198
- $ added = $ this ->connection ->xadd ($ this ->stream , '* ' , ['message ' => json_encode (
199
- ['body ' => $ body , 'headers ' => $ headers ]
200
- )]);
215
+ if ($ this ->maxEntries ) {
216
+ $ added = $ this ->connection ->xadd ($ this ->stream , '* ' , ['message ' => $ message ], $ this ->maxEntries , true );
217
+ } else {
218
+ $ added = $ this ->connection ->xadd ($ this ->stream , '* ' , ['message ' => $ message ]);
219
+ }
201
220
}
202
221
} catch (\RedisException $ e ) {
203
222
}
0 commit comments