@@ -6749,6 +6749,242 @@ var _ = Describe("Commands", func() {
67496749 Expect (err ).NotTo (HaveOccurred ())
67506750 Expect (n ).To (Equal (int64 (2 )))
67516751 })
6752+
6753+ It ("should XReadGroup with CLAIM argument" , func () {
6754+ SkipBeforeRedisVersion (8.3 , "XREADGROUP CLAIM requires Redis 8.3+" )
6755+
6756+ time .Sleep (100 * time .Millisecond )
6757+
6758+ res , err := client .XReadGroup (ctx , & redis.XReadGroupArgs {
6759+ Group : "group" ,
6760+ Consumer : "consumer2" ,
6761+ Streams : []string {"stream" , ">" },
6762+ Claim : 50 * time .Millisecond ,
6763+ }).Result ()
6764+ Expect (err ).NotTo (HaveOccurred ())
6765+ Expect (res ).To (HaveLen (1 ))
6766+ Expect (res [0 ].Stream ).To (Equal ("stream" ))
6767+
6768+ messages := res [0 ].Messages
6769+ Expect (len (messages )).To (BeNumerically (">=" , 1 ))
6770+
6771+ for _ , msg := range messages {
6772+ if msg .MillisElapsedFromDelivery > 0 {
6773+ Expect (msg .MillisElapsedFromDelivery ).To (BeNumerically (">=" , 50 ))
6774+ Expect (msg .DeliveredCount ).To (BeNumerically (">=" , 1 ))
6775+ }
6776+ }
6777+ })
6778+
6779+ It ("should XReadGroup with CLAIM and COUNT" , func () {
6780+ SkipBeforeRedisVersion (8.3 , "XREADGROUP CLAIM requires Redis 8.3+" )
6781+
6782+ time .Sleep (100 * time .Millisecond )
6783+
6784+ res , err := client .XReadGroup (ctx , & redis.XReadGroupArgs {
6785+ Group : "group" ,
6786+ Consumer : "consumer3" ,
6787+ Streams : []string {"stream" , ">" },
6788+ Claim : 50 * time .Millisecond ,
6789+ Count : 2 ,
6790+ }).Result ()
6791+ Expect (err ).NotTo (HaveOccurred ())
6792+
6793+ if len (res ) > 0 && len (res [0 ].Messages ) > 0 {
6794+ Expect (len (res [0 ].Messages )).To (BeNumerically ("<=" , 2 ))
6795+ }
6796+ })
6797+
6798+ It ("should XReadGroup with CLAIM and NOACK" , func () {
6799+ SkipBeforeRedisVersion (8.3 , "XREADGROUP CLAIM requires Redis 8.3+" )
6800+
6801+ time .Sleep (100 * time .Millisecond )
6802+
6803+ res , err := client .XReadGroup (ctx , & redis.XReadGroupArgs {
6804+ Group : "group" ,
6805+ Consumer : "consumer4" ,
6806+ Streams : []string {"stream" , ">" },
6807+ Claim : 50 * time .Millisecond ,
6808+ NoAck : true ,
6809+ }).Result ()
6810+ Expect (err ).NotTo (HaveOccurred ())
6811+
6812+ if len (res ) > 0 {
6813+ Expect (res [0 ].Stream ).To (Equal ("stream" ))
6814+ }
6815+ })
6816+
6817+ It ("should XReadGroup CLAIM empties PEL after acknowledgment" , func () {
6818+ SkipBeforeRedisVersion (8.3 , "XREADGROUP CLAIM requires Redis 8.3+" )
6819+
6820+ time .Sleep (100 * time .Millisecond )
6821+
6822+ res , err := client .XReadGroup (ctx , & redis.XReadGroupArgs {
6823+ Group : "group" ,
6824+ Consumer : "consumer5" ,
6825+ Streams : []string {"stream" , ">" },
6826+ Claim : 50 * time .Millisecond ,
6827+ }).Result ()
6828+ Expect (err ).NotTo (HaveOccurred ())
6829+
6830+ if len (res ) > 0 && len (res [0 ].Messages ) > 0 {
6831+ ids := make ([]string , len (res [0 ].Messages ))
6832+ for i , msg := range res [0 ].Messages {
6833+ ids [i ] = msg .ID
6834+ }
6835+
6836+ n , err := client .XAck (ctx , "stream" , "group" , ids ... ).Result ()
6837+ Expect (err ).NotTo (HaveOccurred ())
6838+ Expect (n ).To (BeNumerically (">=" , 1 ))
6839+
6840+ pending , err := client .XPending (ctx , "stream" , "group" ).Result ()
6841+ Expect (err ).NotTo (HaveOccurred ())
6842+ Expect (pending .Count ).To (BeNumerically ("<" , 3 ))
6843+ }
6844+ })
6845+
6846+ It ("should XReadGroup backward compatibility without CLAIM" , func () {
6847+ res , err := client .XReadGroup (ctx , & redis.XReadGroupArgs {
6848+ Group : "group" ,
6849+ Consumer : "consumer_compat" ,
6850+ Streams : []string {"stream" , "0" },
6851+ }).Result ()
6852+ Expect (err ).NotTo (HaveOccurred ())
6853+ Expect (res ).To (HaveLen (1 ))
6854+ Expect (res [0 ].Stream ).To (Equal ("stream" ))
6855+
6856+ for _ , msg := range res [0 ].Messages {
6857+ Expect (msg .MillisElapsedFromDelivery ).To (Equal (int64 (0 )))
6858+ Expect (msg .DeliveredCount ).To (Equal (int64 (0 )))
6859+ }
6860+ })
6861+
6862+ It ("should XReadGroup CLAIM with multiple streams" , func () {
6863+ SkipBeforeRedisVersion (8.3 , "XREADGROUP CLAIM requires Redis 8.3+" )
6864+
6865+ id , err := client .XAdd (ctx , & redis.XAddArgs {
6866+ Stream : "stream2" ,
6867+ ID : "1-0" ,
6868+ Values : map [string ]interface {}{"field1" : "value1" },
6869+ }).Result ()
6870+ Expect (err ).NotTo (HaveOccurred ())
6871+ Expect (id ).To (Equal ("1-0" ))
6872+
6873+ id , err = client .XAdd (ctx , & redis.XAddArgs {
6874+ Stream : "stream2" ,
6875+ ID : "2-0" ,
6876+ Values : map [string ]interface {}{"field2" : "value2" },
6877+ }).Result ()
6878+ Expect (err ).NotTo (HaveOccurred ())
6879+ Expect (id ).To (Equal ("2-0" ))
6880+
6881+ err = client .XGroupCreate (ctx , "stream2" , "group2" , "0" ).Err ()
6882+ Expect (err ).NotTo (HaveOccurred ())
6883+
6884+ _ , err = client .XReadGroup (ctx , & redis.XReadGroupArgs {
6885+ Group : "group2" ,
6886+ Consumer : "consumer1" ,
6887+ Streams : []string {"stream2" , ">" },
6888+ }).Result ()
6889+ Expect (err ).NotTo (HaveOccurred ())
6890+
6891+ time .Sleep (100 * time .Millisecond )
6892+
6893+ res , err := client .XReadGroup (ctx , & redis.XReadGroupArgs {
6894+ Group : "group2" ,
6895+ Consumer : "consumer2" ,
6896+ Streams : []string {"stream2" , ">" },
6897+ Claim : 50 * time .Millisecond ,
6898+ }).Result ()
6899+ Expect (err ).NotTo (HaveOccurred ())
6900+
6901+ if len (res ) > 0 {
6902+ Expect (res [0 ].Stream ).To (Equal ("stream2" ))
6903+ if len (res [0 ].Messages ) > 0 {
6904+ for _ , msg := range res [0 ].Messages {
6905+ if msg .MillisElapsedFromDelivery > 0 {
6906+ Expect (msg .DeliveredCount ).To (BeNumerically (">=" , 1 ))
6907+ }
6908+ }
6909+ }
6910+ }
6911+ })
6912+
6913+ It ("should XReadGroup CLAIM work consistently on RESP2 and RESP3" , func () {
6914+ SkipBeforeRedisVersion (8.3 , "XREADGROUP CLAIM requires Redis 8.3+" )
6915+
6916+ streamName := "stream-resp-test"
6917+ err := client .XAdd (ctx , & redis.XAddArgs {
6918+ Stream : streamName ,
6919+ Values : map [string ]interface {}{"field1" : "value1" },
6920+ }).Err ()
6921+ Expect (err ).NotTo (HaveOccurred ())
6922+
6923+ err = client .XAdd (ctx , & redis.XAddArgs {
6924+ Stream : streamName ,
6925+ Values : map [string ]interface {}{"field2" : "value2" },
6926+ }).Err ()
6927+ Expect (err ).NotTo (HaveOccurred ())
6928+
6929+ groupName := "resp-test-group"
6930+ err = client .XGroupCreate (ctx , streamName , groupName , "0" ).Err ()
6931+ Expect (err ).NotTo (HaveOccurred ())
6932+
6933+ _ , err = client .XReadGroup (ctx , & redis.XReadGroupArgs {
6934+ Group : groupName ,
6935+ Consumer : "consumer1" ,
6936+ Streams : []string {streamName , ">" },
6937+ }).Result ()
6938+ Expect (err ).NotTo (HaveOccurred ())
6939+
6940+ time .Sleep (100 * time .Millisecond )
6941+
6942+ // Test with RESP2 (protocol 2)
6943+ resp2Client := redis .NewClient (& redis.Options {
6944+ Addr : redisAddr ,
6945+ Protocol : 2 ,
6946+ })
6947+ defer resp2Client .Close ()
6948+
6949+ resp2Result , err := resp2Client .XReadGroup (ctx , & redis.XReadGroupArgs {
6950+ Group : groupName ,
6951+ Consumer : "consumer2" ,
6952+ Streams : []string {streamName , "0" },
6953+ Claim : 50 * time .Millisecond ,
6954+ }).Result ()
6955+ Expect (err ).NotTo (HaveOccurred ())
6956+ Expect (resp2Result ).To (HaveLen (1 ))
6957+
6958+ // Test with RESP3 (protocol 3)
6959+ resp3Client := redis .NewClient (& redis.Options {
6960+ Addr : redisAddr ,
6961+ Protocol : 3 ,
6962+ })
6963+ defer resp3Client .Close ()
6964+
6965+ resp3Result , err := resp3Client .XReadGroup (ctx , & redis.XReadGroupArgs {
6966+ Group : groupName ,
6967+ Consumer : "consumer3" ,
6968+ Streams : []string {streamName , "0" },
6969+ Claim : 50 * time .Millisecond ,
6970+ }).Result ()
6971+ Expect (err ).NotTo (HaveOccurred ())
6972+ Expect (resp3Result ).To (HaveLen (1 ))
6973+
6974+ Expect (len (resp2Result [0 ].Messages )).To (Equal (len (resp3Result [0 ].Messages )))
6975+
6976+ for i := range resp2Result [0 ].Messages {
6977+ msg2 := resp2Result [0 ].Messages [i ]
6978+ msg3 := resp3Result [0 ].Messages [i ]
6979+
6980+ Expect (msg2 .ID ).To (Equal (msg3 .ID ))
6981+
6982+ if msg2 .MillisElapsedFromDelivery > 0 {
6983+ Expect (msg3 .MillisElapsedFromDelivery ).To (BeNumerically (">" , 0 ))
6984+ Expect (msg2 .DeliveredCount ).To (Equal (msg3 .DeliveredCount ))
6985+ }
6986+ }
6987+ })
67526988 })
67536989
67546990 Describe ("xinfo" , func () {
0 commit comments