Signadot can dynamically route http and gRPC requests to specific versions of the destination Service using Signadot DevMesh or a Service Mesh. A specific request header value is used to determine where to route a request. By default requests are routed to the baseline version of Services. If the header contains context for a specific Sandbox, then the request is routed to the forked version of the Service in that Sandbox.
Consider an example where you have Services A, B and C and we have a fork, Service B" in a Sandbox. In the request flow diagram shown below, the dotted orange lines show a request that includes a header with a reference to the Sandbox. This request is routed to the forked version Service B" that's part of the Sandbox. All requests without this header, will flow through Service B.
For this to work, a pre-requisite is for Service A to propagate specific request headers from the incoming requests to all outgoing requests. This is called context propagation. The sections below detail how Signadot makes use of context propagation and how to implement context propagation in your Services.
When Signadot receives a request on an Endpoint, our proxy injects header values to identify the desired sandbox before forwarding the request on to your service.
The goal of context propagation is to ensure that this sandbox metadata survives every step of the subsequent chain of service-to-service requests, so that request routing can occur at any step.
To maximize the chances of this metadata being propagated automatically, we inject multiple, redundant copies in formats that common distributed tracing libraries use for "baggage", which is the conventional name for this kind of arbitrary metadata propagation.
Setting up Context Propagation
Context propagation is commonly achieved using distributed tracing libraries because these libraries can often automatically instrument your code with minimal changes. They do this with request middleware layers that extract data from certain headers in all incoming requests, propagate that data throughout the function call stack, and add the same header values to all outgoing requests made from within that call stack.
Signadot supports the following header formats in HTTP 1/2 and gRPC and the corresponding tracing libraries.
There are two mechanisms of propagation that are supported from the OpenTelemetry specification:
In both of these cases, a key named
sd-routing-key 1 is used to persist information pertaining to Sandboxes. If you're making use of OpenTelemetry instrumentation in your services,
tracestate headers are propagated automatically.
A header named
uberctx-sd-routing-key 1 is expected to be propagated by your services. If you're making use of Jaeger instrumentation in your services, headers in this format are propagated automatically.
A header named
ot-baggage-sd-routing-key 1 is expected to be propagated by your services. If you're using Datadog's Go language instrumentation libraries, headers in this format are propagated automatically. Support in other languages depends on the library being used and the mode in which it's used.
If you are not using the above libraries, we recommend that you make use of the
baggage header as described in the W3C Baggage Specification. Services would need to propagate this header from each incoming request to any outgoing requests the original handler makes.
The headers that will be set on the entry-point service when using a Signadot preview URL will be in the following format and the application must propagate this header as-is (or with modifications according to the W3C spec) to other services in the system.
Header Propagation Examples
Sample code for implementing header propagation in various languages using OpenTelemetry can be found in this GitHub Repository.
- With operators older than v0.11.0, please use
sd-sandbox-idin place of