fix: scope realtime fanout dedup per node
This commit is contained in:
@@ -851,7 +851,7 @@ func (r *redisGroupMessageRuntime) StartRealtimeFanoutSubscriber(ctx context.Con
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if envelope.TenantID.IsValid() && envelope.DedupKey != "" {
|
if envelope.TenantID.IsValid() && envelope.DedupKey != "" {
|
||||||
id := fmt.Sprintf("%d:%s", envelope.TenantID, envelope.DedupKey)
|
id := realtimeFanoutDedupClaimID(envelope.TenantID, nodeID, envelope.DedupKey)
|
||||||
claimed, err := r.ClaimShortState("rt_dedup", id, 5*time.Minute)
|
claimed, err := r.ClaimShortState("rt_dedup", id, 5*time.Minute)
|
||||||
if err != nil || !claimed {
|
if err != nil || !claimed {
|
||||||
continue
|
continue
|
||||||
@@ -1110,6 +1110,13 @@ func (r *redisGroupMessageRuntime) realtimeFanoutPattern() string {
|
|||||||
return strings.TrimSuffix(r.prefix, ":") + ":*:rt:fanout"
|
return strings.TrimSuffix(r.prefix, ":") + ":*:rt:fanout"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func realtimeFanoutDedupClaimID(tenantID types.TenantID, nodeID, dedupKey string) string {
|
||||||
|
if nodeID == "" {
|
||||||
|
nodeID = "local"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d:%s:%s", tenantID, nodeID, dedupKey)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *redisGroupMessageRuntime) objectCacheKey(tenantID types.TenantID, namespace, id string) string {
|
func (r *redisGroupMessageRuntime) objectCacheKey(tenantID types.TenantID, namespace, id string) string {
|
||||||
return r.key(tenantID, "cache", namespace, id)
|
return r.key(tenantID, "cache", namespace, id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,6 +191,20 @@ func TestLoginTokenRevocation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRealtimeFanoutDedupClaimIDIsNodeScoped(t *testing.T) {
|
||||||
|
tenantID := types.TenantID(7)
|
||||||
|
dedupKey := "data:p2pABC:42"
|
||||||
|
|
||||||
|
nodeA := realtimeFanoutDedupClaimID(tenantID, "pod-a", dedupKey)
|
||||||
|
nodeB := realtimeFanoutDedupClaimID(tenantID, "pod-b", dedupKey)
|
||||||
|
if nodeA == nodeB {
|
||||||
|
t.Fatalf("dedup claim id must be node-scoped: %q", nodeA)
|
||||||
|
}
|
||||||
|
if got, want := realtimeFanoutDedupClaimID(tenantID, "", dedupKey), "7:local:data:p2pABC:42"; got != want {
|
||||||
|
t.Fatalf("unexpected local fallback claim id: got %q want %q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMessageRuntimeSeqAndClientMidIdempotency(t *testing.T) {
|
func TestMessageRuntimeSeqAndClientMidIdempotency(t *testing.T) {
|
||||||
oldRuntime := groupMsgRuntime
|
oldRuntime := groupMsgRuntime
|
||||||
runtime := newTestGroupMessageRuntime()
|
runtime := newTestGroupMessageRuntime()
|
||||||
|
|||||||
Reference in New Issue
Block a user