Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ring: Use static types for ingester descriptions in HTTP responses #78

Merged
merged 1 commit into from
Nov 26, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 23 additions & 19 deletions ring/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,24 @@ func (r *Ring) forget(ctx context.Context, id string) error {
return r.KVClient.CAS(ctx, r.key, unregister)
}

type ingesterDesc struct {
ID string `json:"id"`
State string `json:"state"`
Address string `json:"address"`
HeartbeatTimestamp string `json:"timestamp"`
RegisteredTimestamp string `json:"registered_timestamp"`
Zone string `json:"zone"`
Tokens []uint32 `json:"tokens"`
NumTokens int `json:"-"`
Ownership float64 `json:"-"`
}

type httpResponse struct {
Ingesters []ingesterDesc `json:"shards"`
Now time.Time `json:"now"`
ShowTokens bool `json:"-"`
}

func (r *Ring) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if req.Method == http.MethodPost {
ingesterID := req.FormValue("forget")
Expand Down Expand Up @@ -132,7 +150,7 @@ func (r *Ring) ServeHTTP(w http.ResponseWriter, req *http.Request) {
sort.Strings(ingesterIDs)

now := time.Now()
ingesters := []interface{}{}
var ingesters []ingesterDesc
_, owned := r.countTokens()
for _, id := range ingesterIDs {
ing := r.ringDesc.Ingesters[id]
Expand All @@ -148,17 +166,7 @@ func (r *Ring) ServeHTTP(w http.ResponseWriter, req *http.Request) {
registeredTimestamp = ing.GetRegisteredAt().String()
}

ingesters = append(ingesters, struct {
ID string `json:"id"`
State string `json:"state"`
Address string `json:"address"`
HeartbeatTimestamp string `json:"timestamp"`
RegisteredTimestamp string `json:"registered_timestamp"`
Zone string `json:"zone"`
Tokens []uint32 `json:"tokens"`
NumTokens int `json:"-"`
Ownership float64 `json:"-"`
}{
ingesters = append(ingesters, ingesterDesc{
ID: id,
State: state,
Address: ing.Addr,
Expand All @@ -173,11 +181,7 @@ func (r *Ring) ServeHTTP(w http.ResponseWriter, req *http.Request) {

tokensParam := req.URL.Query().Get("tokens")

renderHTTPResponse(w, struct {
Ingesters []interface{} `json:"shards"`
Now time.Time `json:"now"`
ShowTokens bool `json:"-"`
}{
renderHTTPResponse(w, httpResponse{
Ingesters: ingesters,
Now: now,
ShowTokens: tokensParam == "true",
Expand All @@ -186,7 +190,7 @@ func (r *Ring) ServeHTTP(w http.ResponseWriter, req *http.Request) {

// RenderHTTPResponse either responds with json or a rendered html page using the passed in template
// by checking the Accepts header
func renderHTTPResponse(w http.ResponseWriter, v interface{}, t *template.Template, r *http.Request) {
func renderHTTPResponse(w http.ResponseWriter, v httpResponse, t *template.Template, r *http.Request) {
accept := r.Header.Get("Accept")
if strings.Contains(accept, "application/json") {
writeJSONResponse(w, v)
Expand All @@ -200,7 +204,7 @@ func renderHTTPResponse(w http.ResponseWriter, v interface{}, t *template.Templa
}

// WriteJSONResponse writes some JSON as a HTTP response.
func writeJSONResponse(w http.ResponseWriter, v interface{}) {
func writeJSONResponse(w http.ResponseWriter, v httpResponse) {
w.Header().Set("Content-Type", "application/json")

data, err := json.Marshal(v)
Expand Down