http: add an X-Consul-Query-Backend header to responses

So that it is easier to detect and test when streaming is being used.
This commit is contained in:
Daniel Nephin 2021-06-28 16:25:49 -04:00
parent 2e1e80266a
commit 16b21b0864
5 changed files with 42 additions and 0 deletions

View File

@ -723,6 +723,13 @@ func setMeta(resp http.ResponseWriter, m structs.QueryMetaCompat) {
setLastContact(resp, m.GetLastContact())
setKnownLeader(resp, m.GetKnownLeader())
setConsistency(resp, m.GetConsistencyLevel())
setQueryBackend(resp, m.GetBackend())
}
func setQueryBackend(resp http.ResponseWriter, backend structs.QueryBackend) {
if b := backend.String(); b != "" {
resp.Header().Set("X-Consul-Query-Backend", b)
}
}
// setCacheMeta sets http response headers to indicate cache status.

View File

@ -44,6 +44,7 @@ type QueryMetaCompat interface {
SetIndex(uint64)
GetConsistencyLevel() string
SetConsistencyLevel(string)
GetBackend() QueryBackend
}
// GetToken helps implement the QueryOptionsCompat interface
@ -269,3 +270,7 @@ func (q *QueryMeta) SetIndex(index uint64) {
func (q *QueryMeta) SetConsistencyLevel(consistencyLevel string) {
q.ConsistencyLevel = consistencyLevel
}
func (q *QueryMeta) GetBackend() QueryBackend {
return q.Backend
}

View File

@ -339,6 +339,24 @@ func (w WriteRequest) HasTimedOut(start time.Time, rpcHoldTimeout, maxQueryTime,
return time.Since(start) > rpcHoldTimeout
}
type QueryBackend int
const (
QueryBackendBlocking QueryBackend = iota
QueryBackendStreaming
)
func (q QueryBackend) String() string {
switch q {
case QueryBackendBlocking:
return "blocking-query"
case QueryBackendStreaming:
return "streaming"
default:
return ""
}
}
// QueryMeta allows a query response to include potentially
// useful metadata about a query
type QueryMeta struct {
@ -363,6 +381,9 @@ type QueryMeta struct {
// When NotModified is true, the response will not contain the result of
// the query.
NotModified bool
// Backend used to handle this query, either blocking-query or streaming.
Backend QueryBackend
}
// RegisterRequest is used for the Catalog.Register endpoint

View File

@ -2,6 +2,8 @@ package pbcommon
import (
"time"
"github.com/hashicorp/consul/agent/structs"
)
// IsRead is always true for QueryOption
@ -97,6 +99,10 @@ func (q *QueryMeta) SetConsistencyLevel(consistencyLevel string) {
q.ConsistencyLevel = consistencyLevel
}
func (q *QueryMeta) GetBackend() structs.QueryBackend {
return structs.QueryBackend(0)
}
// WriteRequest only applies to writes, always false
func (w WriteRequest) IsRead() bool {
return false

View File

@ -99,6 +99,9 @@ While streaming is a significant optimization over long polling, it will not pop
`X-Consul-LastContact` or `X-Consul-KnownLeader` response headers, because the required
data is not available to the client.
When the streaming backend is used, API responses will include the `X-Consul-Query-Backend`
header with a value of `streaming`.
## Hash-based Blocking Queries