@@ -36,6 +36,7 @@ class Connection
3636
3737 private $ connection ;
3838 private $ stream ;
39+ private $ queue ;
3940 private $ group ;
4041 private $ consumer ;
4142 private $ autoSetup ;
@@ -57,6 +58,7 @@ public function __construct(array $configuration, array $connectionCredentials =
5758 }
5859
5960 $ this ->stream = $ configuration ['stream ' ] ?? self ::DEFAULT_OPTIONS ['stream ' ];
61+ $ this ->queue = $ this ->stream .'_queue ' ;
6062 $ this ->group = $ configuration ['group ' ] ?? self ::DEFAULT_OPTIONS ['group ' ];
6163 $ this ->consumer = $ configuration ['consumer ' ] ?? self ::DEFAULT_OPTIONS ['consumer ' ];
6264 $ this ->autoSetup = $ configuration ['auto_setup ' ] ?? self ::DEFAULT_OPTIONS ['auto_setup ' ];
@@ -112,6 +114,18 @@ public function get(): ?array
112114 $ this ->setup ();
113115 }
114116
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+
115129 $ messageId = '> ' ; // will receive new messages
116130
117131 if ($ this ->couldHavePendingMessages ) {
@@ -182,22 +196,27 @@ public function reject(string $id): void
182196 }
183197 }
184198
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
186203 {
187204 if ($ this ->autoSetup ) {
188205 $ this ->setup ();
189206 }
190207
191208 $ e = null ;
192209 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 );
197214 } 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+ }
201220 }
202221 } catch (\RedisException $ e ) {
203222 }
0 commit comments