@@ -25,6 +25,10 @@ type ConcurrencyCacheSuite struct {
2525 cache service.ConcurrencyCache
2626}
2727
28+ func TestConcurrencyCacheSuite (t * testing.T ) {
29+ suite .Run (t , new (ConcurrencyCacheSuite ))
30+ }
31+
2832func (s * ConcurrencyCacheSuite ) SetupTest () {
2933 s .IntegrationRedisSuite .SetupTest ()
3034 s .cache = NewConcurrencyCache (s .rdb , testSlotTTLMinutes , int (testSlotTTL .Seconds ()))
@@ -247,17 +251,41 @@ func (s *ConcurrencyCacheSuite) TestAccountWaitQueue_IncrementAndDecrement() {
247251 require .Equal (s .T (), 1 , val , "expected account wait count 1" )
248252}
249253
250- func (s * ConcurrencyCacheSuite ) TestAccountWaitQueue_DecrementNoNegative () {
251- accountID := int64 (301 )
252- waitKey := fmt .Sprintf ("%s%d" , accountWaitKeyPrefix , accountID )
254+ func (s * ConcurrencyCacheSuite ) TestCleanupStaleProcessSlots () {
255+ accountID := int64 (901 )
256+ userID := int64 (902 )
257+ accountKey := fmt .Sprintf ("%s%d" , accountSlotKeyPrefix , accountID )
258+ userKey := fmt .Sprintf ("%s%d" , userSlotKeyPrefix , userID )
259+ userWaitKey := fmt .Sprintf ("%s%d" , waitQueueKeyPrefix , userID )
260+ accountWaitKey := fmt .Sprintf ("%s%d" , accountWaitKeyPrefix , accountID )
253261
254- require .NoError (s .T (), s .cache .DecrementAccountWaitCount (s .ctx , accountID ), "DecrementAccountWaitCount on non-existent key" )
262+ now := time .Now ().Unix ()
263+ require .NoError (s .T (), s .rdb .ZAdd (s .ctx , accountKey ,
264+ redis.Z {Score : float64 (now ), Member : "oldproc-1" },
265+ redis.Z {Score : float64 (now ), Member : "keep-1" },
266+ ).Err ())
267+ require .NoError (s .T (), s .rdb .ZAdd (s .ctx , userKey ,
268+ redis.Z {Score : float64 (now ), Member : "oldproc-2" },
269+ redis.Z {Score : float64 (now ), Member : "keep-2" },
270+ ).Err ())
271+ require .NoError (s .T (), s .rdb .Set (s .ctx , userWaitKey , 3 , time .Minute ).Err ())
272+ require .NoError (s .T (), s .rdb .Set (s .ctx , accountWaitKey , 2 , time .Minute ).Err ())
273+
274+ require .NoError (s .T (), s .cache .CleanupStaleProcessSlots (s .ctx , "keep-" ))
275+
276+ accountMembers , err := s .rdb .ZRange (s .ctx , accountKey , 0 , - 1 ).Result ()
277+ require .NoError (s .T (), err )
278+ require .Equal (s .T (), []string {"keep-1" }, accountMembers )
255279
256- val , err := s .rdb .Get (s .ctx , waitKey ).Int ()
257- if ! errors .Is (err , redis .Nil ) {
258- require .NoError (s .T (), err , "Get waitKey" )
259- }
260- require .GreaterOrEqual (s .T (), val , 0 , "expected non-negative account wait count after decrement on empty" )
280+ userMembers , err := s .rdb .ZRange (s .ctx , userKey , 0 , - 1 ).Result ()
281+ require .NoError (s .T (), err )
282+ require .Equal (s .T (), []string {"keep-2" }, userMembers )
283+
284+ _ , err = s .rdb .Get (s .ctx , userWaitKey ).Result ()
285+ require .True (s .T (), errors .Is (err , redis .Nil ))
286+
287+ _ , err = s .rdb .Get (s .ctx , accountWaitKey ).Result ()
288+ require .True (s .T (), errors .Is (err , redis .Nil ))
261289}
262290
263291func (s * ConcurrencyCacheSuite ) TestGetAccountConcurrency_Missing () {
@@ -407,6 +435,53 @@ func (s *ConcurrencyCacheSuite) TestCleanupExpiredAccountSlots_NoExpired() {
407435 require .Equal (s .T (), 2 , cur )
408436}
409437
410- func TestConcurrencyCacheSuite (t * testing.T ) {
411- suite .Run (t , new (ConcurrencyCacheSuite ))
438+ func (s * ConcurrencyCacheSuite ) TestCleanupStaleProcessSlots_RemovesOldPrefixesAndWaitCounters () {
439+ accountID := int64 (901 )
440+ userID := int64 (902 )
441+ accountSlotKey := fmt .Sprintf ("%s%d" , accountSlotKeyPrefix , accountID )
442+ userSlotKey := fmt .Sprintf ("%s%d" , userSlotKeyPrefix , userID )
443+ userWaitKey := fmt .Sprintf ("%s%d" , waitQueueKeyPrefix , userID )
444+ accountWaitKey := fmt .Sprintf ("%s%d" , accountWaitKeyPrefix , accountID )
445+
446+ now := float64 (time .Now ().Unix ())
447+ require .NoError (s .T (), s .rdb .ZAdd (s .ctx , accountSlotKey ,
448+ redis.Z {Score : now , Member : "oldproc-1" },
449+ redis.Z {Score : now , Member : "activeproc-1" },
450+ ).Err ())
451+ require .NoError (s .T (), s .rdb .Expire (s .ctx , accountSlotKey , testSlotTTL ).Err ())
452+ require .NoError (s .T (), s .rdb .ZAdd (s .ctx , userSlotKey ,
453+ redis.Z {Score : now , Member : "oldproc-2" },
454+ redis.Z {Score : now , Member : "activeproc-2" },
455+ ).Err ())
456+ require .NoError (s .T (), s .rdb .Expire (s .ctx , userSlotKey , testSlotTTL ).Err ())
457+ require .NoError (s .T (), s .rdb .Set (s .ctx , userWaitKey , 3 , testSlotTTL ).Err ())
458+ require .NoError (s .T (), s .rdb .Set (s .ctx , accountWaitKey , 2 , testSlotTTL ).Err ())
459+
460+ require .NoError (s .T (), s .cache .CleanupStaleProcessSlots (s .ctx , "activeproc-" ))
461+
462+ accountMembers , err := s .rdb .ZRange (s .ctx , accountSlotKey , 0 , - 1 ).Result ()
463+ require .NoError (s .T (), err )
464+ require .Equal (s .T (), []string {"activeproc-1" }, accountMembers )
465+
466+ userMembers , err := s .rdb .ZRange (s .ctx , userSlotKey , 0 , - 1 ).Result ()
467+ require .NoError (s .T (), err )
468+ require .Equal (s .T (), []string {"activeproc-2" }, userMembers )
469+
470+ _ , err = s .rdb .Get (s .ctx , userWaitKey ).Result ()
471+ require .ErrorIs (s .T (), err , redis .Nil )
472+ _ , err = s .rdb .Get (s .ctx , accountWaitKey ).Result ()
473+ require .ErrorIs (s .T (), err , redis .Nil )
474+ }
475+
476+ func (s * ConcurrencyCacheSuite ) TestCleanupStaleProcessSlots_DeletesEmptySlotKeys () {
477+ accountID := int64 (903 )
478+ accountSlotKey := fmt .Sprintf ("%s%d" , accountSlotKeyPrefix , accountID )
479+ require .NoError (s .T (), s .rdb .ZAdd (s .ctx , accountSlotKey , redis.Z {Score : float64 (time .Now ().Unix ()), Member : "oldproc-1" }).Err ())
480+ require .NoError (s .T (), s .rdb .Expire (s .ctx , accountSlotKey , testSlotTTL ).Err ())
481+
482+ require .NoError (s .T (), s .cache .CleanupStaleProcessSlots (s .ctx , "activeproc-" ))
483+
484+ exists , err := s .rdb .Exists (s .ctx , accountSlotKey ).Result ()
485+ require .NoError (s .T (), err )
486+ require .EqualValues (s .T (), 0 , exists )
412487}
0 commit comments