11import Redis , { ChainableCommander , RedisOptions } from 'ioredis'
22import { RedisStream } from './stream.js'
33import mkDebug from 'debug'
4- import { XBatchResult , XStreamResult , env } from './types.js'
4+ import { XStreamResult , env } from './types.js'
55
66const debug = mkDebug ( 'redis-x-stream' )
77
@@ -16,8 +16,15 @@ function isNumber(num: number | string | undefined): num is number {
1616export async function readAckDelete (
1717 stream : RedisStream
1818) : Promise < IterableIterator < XStreamResult > | undefined > {
19- const pipeline = stream . client . pipeline ( ) ,
20- read = stream . group ? xreadgroup : xread
19+ const pipeline = stream . client . pipeline ( )
20+
21+ if ( stream . draining ) {
22+ ack ( pipeline , stream )
23+ await pipeline . exec ( )
24+ return
25+ }
26+
27+ const read = stream . group ? xreadgroup : xread
2128 xgroup ( pipeline , stream )
2229 ack ( pipeline , stream )
2330 read ( pipeline , stream )
@@ -27,17 +34,17 @@ export async function readAckDelete(
2734 return
2835 }
2936
30- //TODO: NOGROUP the consumer group this client was blocked on no longer exists
37+ //TODO: FATAL - NOGROUP the consumer group this client was blocked on no longer exists
3138 for ( const result of responses ) {
3239 if ( result [ 0 ] && ! result [ 0 ] ?. message . startsWith ( 'BUSYGROUP' ) ) {
3340 throw responses [ 0 ]
3441 }
3542 }
36- const result = responses [ responses . length - 1 ] [ 1 ] as XBatchResult | null
43+ const result = responses [ responses . length - 1 ] [ 1 ] as XStreamResult [ ] | null
3744 if ( ! result ) {
3845 return
3946 }
40- if ( read === xreadgroup ) {
47+ if ( stream . group ) {
4148 for ( const stream of result ) {
4249 if ( stream [ 1 ] . length ) {
4350 return result [ Symbol . iterator ] ( )
@@ -48,7 +55,10 @@ export async function readAckDelete(
4855 }
4956}
5057
51- function ack ( client : ChainableCommander , { deleteOnAck, pendingAcks, group } : RedisStream ) : void {
58+ export function ack (
59+ client : ChainableCommander ,
60+ { deleteOnAck, pendingAcks, group } : RedisStream
61+ ) : void {
5262 if ( ! group || ! pendingAcks . size ) return
5363 for ( const [ stream , ids ] of pendingAcks ) {
5464 client . xack ( stream , group , ...ids )
@@ -69,38 +79,29 @@ function xread(client: ChainableCommander, { block, count, streams, buffers }: R
6979 block = block === Infinity ? 0 : block
7080 const args : Parameters < typeof client [ 'xread' ] > = [ 'COUNT' , count ] as IncrementalParameters
7181 if ( isNumber ( block ) ) args . unshift ( 'BLOCK' , block )
82+ args . push ( 'STREAMS' , ...streams . keys ( ) , ...streams . values ( ) )
7283 debug ( `xread ${ args . join ( ' ' ) } ` )
73- client [ buffers ? 'xreadBuffer' : 'xread' ] (
74- ...args ,
75- 'STREAMS' ,
76- ...streams . keys ( ) ,
77- ...streams . values ( )
78- )
84+ client [ buffers ? 'xreadBuffer' : 'xread' ] ( ...args )
7985}
8086
8187function xreadgroup (
8288 client : ChainableCommander ,
83- { block, count, group, consumer, noack, streams, buffers } : RedisStream
89+ { block, count, first , group, consumer, noack, streams, buffers } : RedisStream
8490) : void {
8591 block = block === Infinity ? 0 : block
8692 const args : Parameters < typeof client [ 'xreadgroup' ] > = [
8793 'GROUP' ,
8894 group as string ,
8995 consumer as string ,
90- 'COUNT' ,
91- count . toString ( ) ,
9296 ] as IncrementalParameters
97+ if ( ! first ) args . push ( 'COUNT' , count . toString ( ) )
9398 if ( noack ) args . push ( 'NOACK' )
9499 if ( isNumber ( block ) ) args . push ( 'BLOCK' , block . toString ( ) )
100+ args . push ( 'STREAMS' , ...streams . keys ( ) , ...streams . values ( ) )
95101 debug ( `xreadgroup ${ args . join ( ' ' ) } ` )
96102 // eslint-disable-next-line @typescript-eslint/no-explicit-any
97103 // https://github.com/luin/ioredis/pull/1676#issue-1437398115
98- ; ( client as any ) [ buffers ? 'xreadgroupBuffer' : 'xreadgroup' ] (
99- ...args ,
100- 'STREAMS' ,
101- ...streams . keys ( ) ,
102- ...streams . values ( )
103- )
104+ ; ( client as KindaAny ) [ buffers ? 'xreadgroupBuffer' : 'xreadgroup' ] ( ...args )
104105}
105106
106107export function createClient ( options ?: Redis | string | RedisOptions ) {
0 commit comments