Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/perfect-panel/server/internal/config"
|
||||
"github.com/perfect-panel/server/internal/svc"
|
||||
)
|
||||
|
||||
func clearAllSessions(ctx context.Context, svcCtx *svc.ServiceContext, userID int64) error {
|
||||
userIDText := strconv.FormatInt(userID, 10)
|
||||
sessionSet := make(map[string]struct{})
|
||||
|
||||
pattern := fmt.Sprintf("%s:*", config.SessionIdKey)
|
||||
var cursor uint64
|
||||
for {
|
||||
keys, nextCursor, err := svcCtx.Redis.Scan(ctx, cursor, pattern, 200).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, sessionKey := range keys {
|
||||
value, err := svcCtx.Redis.Get(ctx, sessionKey).Result()
|
||||
if err != nil || value != userIDText {
|
||||
continue
|
||||
}
|
||||
sessionID := strings.TrimPrefix(sessionKey, config.SessionIdKey+":")
|
||||
if sessionID == "" || strings.HasPrefix(sessionID, "detail:") {
|
||||
continue
|
||||
}
|
||||
sessionSet[sessionID] = struct{}{}
|
||||
}
|
||||
cursor = nextCursor
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(sessionSet) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
deviceKeySet := make(map[string]struct{})
|
||||
devicePattern := fmt.Sprintf("%s:*", config.DeviceCacheKeyKey)
|
||||
cursor = 0
|
||||
for {
|
||||
keys, nextCursor, err := svcCtx.Redis.Scan(ctx, cursor, devicePattern, 200).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, deviceKey := range keys {
|
||||
sessionID, err := svcCtx.Redis.Get(ctx, deviceKey).Result()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if _, exists := sessionSet[sessionID]; exists {
|
||||
deviceKeySet[deviceKey] = struct{}{}
|
||||
}
|
||||
}
|
||||
cursor = nextCursor
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
sessionsKey := fmt.Sprintf("%s%v", config.UserSessionsKeyPrefix, userID)
|
||||
pipe := svcCtx.Redis.TxPipeline()
|
||||
for sessionID := range sessionSet {
|
||||
pipe.Del(ctx, fmt.Sprintf("%v:%v", config.SessionIdKey, sessionID))
|
||||
pipe.Del(ctx, fmt.Sprintf("%s:detail:%s", config.SessionIdKey, sessionID))
|
||||
pipe.ZRem(ctx, sessionsKey, sessionID)
|
||||
}
|
||||
pipe.Del(ctx, sessionsKey)
|
||||
for deviceKey := range deviceKeySet {
|
||||
pipe.Del(ctx, deviceKey)
|
||||
}
|
||||
_, err := pipe.Exec(ctx)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user