Interface status: public extension boundary. Concrete trait names may migrate toward the canonical interfaces below; private server helpers are not API.
network request -> ProtocolServer -> ProtocolAdapter -> QueryService
|
ExactQueryClient
ProtocolServerowns transport, authentication context, limits, timeout, and cancellation.ProtocolAdapterconverts protocol-specific data to/from canonical query structures.QueryServiceperforms plan-aware execution.ExactQueryClientis called only for an explicit fallback route.
pub trait ProtocolAdapter: Send + Sync {
type Request;
type Response;
type Error;
fn decode(&self, request: Self::Request)
-> Result<QueryRequest, Self::Error>;
fn encode(&self, response: QueryResponse)
-> Result<Self::Response, Self::Error>;
fn encode_error(&self, error: QueryError) -> Self::Response;
}pub trait ProtocolServer {
type Error;
async fn serve<S>(&self, service: Arc<S>) -> Result<(), Self::Error>
where
S: QueryService<Error = QueryError> + Send + Sync + 'static;
}pub trait ExactQueryClient: Send + Sync {
type Error;
async fn execute_exact(&self, request: &QueryRequest)
-> Result<QueryResponse, Self::Error>;
fn capabilities(&self) -> ExactBackendCapabilities;
}
pub struct ExactBackendCapabilities {
pub backend_id: String,
pub query_languages: Vec<QueryLanguage>,
pub supports_instant: bool,
pub supports_range: bool,
pub maximum_range: Option<Duration>,
}QueryRequest and QueryResponse are defined in
Query routing and readout. They preserve tenant,
query language/expression, logical evaluation range, requested accuracy,
result labels/timestamps/type, source, guarantee, and coverage.
Why these interfaces exist: transport/protocol extensions cannot bypass catalog-backed QueryPlan routing or directly access summary storage, and fallback backends cannot silently reinterpret a request.
- Implement
ProtocolAdapterfor its request/response types. - Map every supported evaluation-time/range and tenant field.
- Preserve Prometheus label/timestamp/result/error semantics where applicable.
- Verify decode→canonical→encode round trips for success and error cases.
- Implement
ProtocolServerand inject only the publicQueryService. - Propagate cancellation, timeout, authentication, and request limits.
- Never call
SummaryStoreor an exact client directly. - Verify cancelled requests stop downstream work and transport errors map
through
encode_error.
- Implement
ExactQueryClientand declareExactBackendCapabilities. - Forward the canonical logical range and tenant unchanged.
- Return exact
QueryResponseor a visible error. - Verify unsupported capability and remote failure do not return an empty successful result.
- Adapter output is canonical input, not a routing decision.
- Server success means the response was transported, not that it was summary-backed.
- Inspect
QueryResponse.sourceto distinguish summary and exact fallback. - End-to-end tests must include one supported request, one explicit fallback, one malformed request, and one backend failure.