Repository navigation
Per-flag delta sync over FlagSyncService #2080
Replies: 3 comments
|
@raflFaisal How should changes to top-level configuration be handled? |
|
Few questions I see unanswered:
Separately, we should evaluate the existing experimental |
|
I think the proposal can be strengthened by defining convergence separately from transport revision continuity. Revisions detect dropped responses, but not an upstream update missed before a revision is assigned. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Details
Background
Current
FlagSyncService.SyncFlagsalways returns a fullflag_configurationsnapshot per message. At scale, this introduces few problems such as:
A per-flag delta protocol would let the server emit
O(changed_flags)ratherthan
O(total_flags)on each notification.Proposal
Extend
flagd.sync.v1additively:POC with delta support: flagd when receiving a delta flag update
The logs show that flagd receives only the delta update for the changed flag, rather than the complete set of flags mapped to the selector.
The updated flag is then appended/upserted in the in-memory store, while all other existing flags remain intact.
This reduces unnecessary network traffic and processing and memory overhead, as only the changed flag needs to be transmitted and processed, helping keep the flag backend service healthy and making it easier to scale as the number of flags and clients increases.
Contract
Capability handshake and single opt-in gate. All new fields in
SyncFlagsResponse(is_delta,flag_ops,revision) MUST only be set when the client advertisedSyncFlagsRequest.supports_deltas=true. For any other client, the server MUST build responses that leave these fields unset — i.e., byte-identical to the pre-feature wire format.Initial snapshot first. For each successful
SyncFlagsRPC invocation, the server MUST send a full snapshot as the first response before sending any delta. For clients that advertisedsupports_deltas=true, this baseline may start with revision 1.Reconnect re-establishes baseline. Every reconnect gets a fresh initial snapshot and a fresh revision sequence. Deltas lost during a disconnect are superseded by the new baseline — the server does not back-fill.
Op semantics.
OP_UPSERTis add-or-replace;OP_DELETEis remove. Clients MUST skipOP_UNSPECIFIEDand any unknown op values to preserve forward compatibility.Batching. A single response MAY carry N ops in
flag_ops.Mixed state is forbidden. Within one message,
is_delta=truemeansflag_configurationis unused;is_delta=falsemeansflag_opsis unused. Servers MUST NOT populate both.Revision stamping (opt-in clients only). For clients that advertised
supports_deltas=true, everySyncFlagsResponse, snapshot or delta, carries a revision. Revisions are per-stream and strictly monotonic:revision_{n+1} = revision_n + 1On a new stream (reconnect), the counter restarts at 1 and the first message is always a full snapshot. This is orthogonal to
is_delta: the one-message-one-revision-bump invariant applies to snapshots and deltas alike.Gap detection and recovery. A client that observes
revision_n != previous+1MUST close the stream and reconnect.Config knob
flagd (and other delta-aware clients) exposes a per-source boolean
supportsDeltasonSourceConfig. When true:supports_deltas=trueonSyncFlagsRequest.Default is
falsefor backward compatibility. Enabling it is opt-in persource.
Compatibility
Additive proto change at new tag numbers (3, 4, 5). Older servers/clients ignore unknown fields. Mixed-version fleets stay correct in every
combination:
Old server + new client (opted in): The client sets
supports_deltas=true, but the server does not know the field. The serveremits snapshots only, with no new fields set. The client sees
revision=0on every message, so gap detection is disabled and the delta path never fires. Snapshots work as before.Old server + new client (not opted in): Identical to the row above.
New server + old client: The client does not set the field (zero-value
false). The server reads it as "not delta-capable", gates allnew fields off, and emits byte-identical wire format to the pre-feature server. The old client is behaviorally and byte-wise unaware the feature exists.
New server + new client (not opted in): Same as the row above: the client is new but has not advertised capability, so the server behaves as if it were old. There is zero visible change for the client.
New server + new client (opted in): Initial snapshot at
revision=1, deltas flow thereafter with contiguous revisions. On a gap or disconnect, the client reconnects and starts over atrevision=1.All reactions