From 267f2312cd7f6014126661950347f8d66495a57a Mon Sep 17 00:00:00 2001 From: Anoop Saxena Date: Tue, 14 Apr 2026 15:30:45 +0530 Subject: [PATCH] Spec: clarify retries, reconciliation, feature ID guidance --- connection-coordinator/docs/Protocols.md | 46 +++++++++++++++++++ connection-coordinator/paths/connections.yaml | 7 ++- connection-coordinator/paths/features.yaml | 14 +++++- connection-coordinator/schemas/feature.yaml | 6 +++ 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/connection-coordinator/docs/Protocols.md b/connection-coordinator/docs/Protocols.md index 506a681..874d73a 100644 --- a/connection-coordinator/docs/Protocols.md +++ b/connection-coordinator/docs/Protocols.md @@ -169,6 +169,52 @@ as connections and features. Note: In the future we may add support for mutating these resources to the API spec. +## **Reliability and Retry Protocols** + +Providers MUST implement the Connection Coordinator API in a way that is safe +under retries and transient failures. Callers MUST assume that requests may be +processed by the remote provider even if the caller times out. + +### **Retries for timeouts and HTTP 5xx** + +For network timeouts and transient server-side failures (HTTP 5xx), callers: + +* SHOULD retry requests using exponential backoff with jitter. +* SHOULD use a bounded retry budget (RECOMMENDED: up to 5 attempts and/or a + total elapsed time budget of ~60 seconds). +* MUST reuse the same fully-qualified resource name / identifiers when + retrying (e.g., the same `connectionId` and `featureId`). This ensures + idempotency. + +If a caller exhausts the retry budget, it MUST stop synchronous retries and +SHOULD transition to a reconciliation / redrive workflow (see below). + +### **Throttling (HTTP 429)** + +Providers MAY return HTTP 429 (Too Many Requests) for throttling. + +* If a provider returns 429, it SHOULD include `Retry-After`. +* Callers MUST respect `Retry-After` when present. + +### **Reconciliation / redrive** + +After transient errors or timeouts, callers SHOULD reconcile remote state before +proceeding. Reconciliation is typically implemented by using `Get*` / `List*` +operations to determine whether the remote resource exists and is in the +expected state. Providers may also implement background redrive to converge the +remote provider to the expected state without causing unbounded retry storms. + +### **Feature identity and invariants** + +* Feature IDs (`featureId`) MUST be treated as opaque identifiers. UUIDv4 is + RECOMMENDED. +* Callers MUST persist feature IDs locally so they can later `GetFeature` and + `DeleteFeature` reliably. +* Providers SHOULD enforce an invariant that there is at most one + `FEATURE_TYPE_L3_BASE` Feature per `(connection, channel)`. Attempts to + create a second `FEATURE_TYPE_L3_BASE` for the same `(connection, channel)` + SHOULD be rejected with HTTP 409 (Conflict). + ## **Customer Connection Workflow** When a customer is looking to make a connection, there are 3 milestones that diff --git a/connection-coordinator/paths/connections.yaml b/connection-coordinator/paths/connections.yaml index 6599392..8ab4cd1 100644 --- a/connection-coordinator/paths/connections.yaml +++ b/connection-coordinator/paths/connections.yaml @@ -55,8 +55,11 @@ AllConnections: If connection creation fails, the provider should restart their call flow refreshing any environment and interconnect details used to create the - request and retry. When retrying, client should use an exponential - backoff strategy for up to 60 seconds. + request and retry. When retrying, clients SHOULD use an exponential + backoff strategy with jitter and a bounded retry budget (RECOMMENDED: up + to 5 attempts and/or up to ~60 seconds total). After exhausting the retry + budget, callers SHOULD reconcile remote state (Get/List) before + proceeding. Errors: 409: CONFLICT. The resource is being created or has already been diff --git a/connection-coordinator/paths/features.yaml b/connection-coordinator/paths/features.yaml index 15973ce..37a63fa 100644 --- a/connection-coordinator/paths/features.yaml +++ b/connection-coordinator/paths/features.yaml @@ -61,12 +61,18 @@ AllFeatures: If *any* errors occur in the described flow, the remote provider is responsible for reconciling the server's state to determine if an existing - request is in flight, retrying the provisioning flow with new parameters, + request is in flight, retrying the provisioning flow with bounded retries + (exponential backoff + jitter), retrying with new parameters when needed, or cleaning up resources and rejecting the customer's provisioning request. Errors: - 409: CONFLICT. Returned when a server detect concurrent updates to the + 409: CONFLICT. Returned when a server detects concurrent updates to the resource. + + 409: CONFLICT. Providers SHOULD enforce that at most one + FEATURE_TYPE_L3_BASE Feature exists per (connection, channel). Attempts + to create a second L3_BASE feature for the same (connection, channel) + SHOULD be rejected with 409. operationId: CreateFeature parameters: - $ref: "../parameters/_index.yaml#/parameters/provider" @@ -76,6 +82,10 @@ AllFeatures: - description: |- Required. The ID to use for the feature, which will become the final component of the feature's resource name. + + Feature IDs MUST be treated as opaque identifiers. UUIDv4 is RECOMMENDED. + Callers SHOULD persist feature IDs locally to allow reliable reconciliation and + delete operations. explode: true in: query name: featureId diff --git a/connection-coordinator/schemas/feature.yaml b/connection-coordinator/schemas/feature.yaml index 7707b48..4b0a23d 100644 --- a/connection-coordinator/schemas/feature.yaml +++ b/connection-coordinator/schemas/feature.yaml @@ -13,6 +13,12 @@ Feature: Identifier. A unique identifier for the feature resource. Format: providers/{provider}/environments/{environment}/interconnects/{interconnect}/connections/{connection}/features/{feature} + + Feature IDs MUST be treated as opaque identifiers. UUIDv4 is RECOMMENDED. + + Providers SHOULD enforce that at most one FEATURE_TYPE_L3_BASE Feature exists + per (connection, channel). Attempts to create a second L3_BASE feature for the + same (connection, channel) SHOULD be rejected with HTTP 409 (Conflict). type: string channel: description: |-