feat(desktop&tenant): Enhance desktop account and task consumer presence management
Desktop Client Build / Resolve Build Metadata (push) Successful in 1m13s
Desktop Client Build / Build Desktop Client (push) Has been cancelled
Desktop Client Build / Publish Client Artifacts to NAS (push) Has been cancelled
Backend CI / Backend (push) Failing after 13m49s
Frontend CI / Frontend (push) Successful in 6m38s
Desktop Client Build / Resolve Build Metadata (push) Successful in 1m13s
Desktop Client Build / Build Desktop Client (push) Has been cancelled
Desktop Client Build / Publish Client Artifacts to NAS (push) Has been cancelled
Backend CI / Backend (push) Failing after 13m49s
Frontend CI / Frontend (push) Successful in 6m38s
- Added new fields to DesktopAccountInfo for tracking account session and task consumer online status, along with queued publish task count and oldest queued publish task timestamp. - Updated DesktopDispatchEvent to include server time for better synchronization. - Implemented separate presence management for task consumers, including marking presence and loading presence state. - Enhanced DesktopAccountService to apply publish queue summaries and manage task consumer presence. - Introduced new methods for replaying queued publish tasks in DesktopDispatchHandler. - Updated tests to cover new presence management logic and ensure correct behavior of account session and task consumer online status.
This commit is contained in:
@@ -14,11 +14,16 @@ import (
|
||||
// as offline within one TTL even when the explicit offline request is missed.
|
||||
const desktopClientPresenceTTL = 30 * time.Second
|
||||
const desktopAccountPresenceTTL = 30 * time.Second
|
||||
const desktopTaskConsumerPresenceTTL = 75 * time.Second
|
||||
|
||||
func desktopClientPresenceKey(clientID uuid.UUID) string {
|
||||
return "desktop:presence:client:" + clientID.String()
|
||||
}
|
||||
|
||||
func desktopTaskConsumerPresenceKey(clientID uuid.UUID) string {
|
||||
return "desktop:presence:task_consumer:" + clientID.String()
|
||||
}
|
||||
|
||||
func desktopAccountPresenceKey(accountID uuid.UUID) string {
|
||||
return "desktop:presence:account:" + accountID.String()
|
||||
}
|
||||
@@ -42,6 +47,18 @@ func markDesktopClientPresent(ctx context.Context, redis *goredis.Client, client
|
||||
_ = redis.Set(ctx, desktopClientPresenceKey(clientID), time.Now().UTC().Format(time.RFC3339), desktopClientPresenceTTL).Err()
|
||||
}
|
||||
|
||||
func markDesktopTaskConsumerPresent(ctx context.Context, redis *goredis.Client, clientID uuid.UUID) {
|
||||
if redis == nil || clientID == uuid.Nil {
|
||||
return
|
||||
}
|
||||
|
||||
_ = redis.Set(ctx, desktopTaskConsumerPresenceKey(clientID), time.Now().UTC().Format(time.RFC3339), desktopTaskConsumerPresenceTTL).Err()
|
||||
}
|
||||
|
||||
func MarkDesktopTaskConsumerPresent(ctx context.Context, redis *goredis.Client, clientID uuid.UUID) {
|
||||
markDesktopTaskConsumerPresent(ctx, redis, clientID)
|
||||
}
|
||||
|
||||
func markDesktopClientPresentForUser(ctx context.Context, redis *goredis.Client, clientID uuid.UUID, tenantID, workspaceID, userID int64) {
|
||||
markDesktopClientPresent(ctx, redis, clientID)
|
||||
if redis == nil || clientID == uuid.Nil || tenantID == 0 || workspaceID == 0 || userID == 0 {
|
||||
@@ -66,7 +83,7 @@ func clearDesktopClientPresence(ctx context.Context, redis *goredis.Client, clie
|
||||
return
|
||||
}
|
||||
|
||||
_ = redis.Del(ctx, desktopClientPresenceKey(clientID)).Err()
|
||||
_ = redis.Del(ctx, desktopClientPresenceKey(clientID), desktopTaskConsumerPresenceKey(clientID)).Err()
|
||||
}
|
||||
|
||||
func clearDesktopClientPresenceStateForUser(ctx context.Context, redis *goredis.Client, clientID uuid.UUID, tenantID, workspaceID, userID int64) {
|
||||
@@ -115,6 +132,44 @@ func loadDesktopClientPresence(ctx context.Context, redis *goredis.Client, clien
|
||||
return result
|
||||
}
|
||||
|
||||
func loadDesktopTaskConsumerPresence(ctx context.Context, redis *goredis.Client, clientIDs []uuid.UUID) map[uuid.UUID]bool {
|
||||
if redis == nil || len(clientIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
uniqueIDs := make([]uuid.UUID, 0, len(clientIDs))
|
||||
seen := make(map[uuid.UUID]struct{}, len(clientIDs))
|
||||
for _, clientID := range clientIDs {
|
||||
if clientID == uuid.Nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[clientID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[clientID] = struct{}{}
|
||||
uniqueIDs = append(uniqueIDs, clientID)
|
||||
}
|
||||
if len(uniqueIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
pipe := redis.Pipeline()
|
||||
cmds := make(map[uuid.UUID]*goredis.IntCmd, len(uniqueIDs))
|
||||
for _, clientID := range uniqueIDs {
|
||||
cmds[clientID] = pipe.Exists(ctx, desktopTaskConsumerPresenceKey(clientID))
|
||||
}
|
||||
|
||||
if _, err := pipe.Exec(ctx); err != nil && err != goredis.Nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make(map[uuid.UUID]bool, len(cmds))
|
||||
for clientID, cmd := range cmds {
|
||||
result[clientID] = cmd.Val() > 0
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func loadDesktopUserOnlineClientCount(ctx context.Context, redis *goredis.Client, tenantID, workspaceID, userID int64, now time.Time) (int, bool) {
|
||||
if redis == nil || tenantID == 0 || workspaceID == 0 || userID == 0 {
|
||||
return 0, false
|
||||
|
||||
Reference in New Issue
Block a user