From 7a8f0135b35ca43a58483873527bc992b8fcc740 Mon Sep 17 00:00:00 2001 From: Matthew Jaffee Date: Mon, 6 Dec 2021 10:36:55 -0600 Subject: [PATCH] redirect GetTranslateData if node doesn't own partition --- api.go | 18 ++++++++++++++++++ http/handler.go | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/api.go b/api.go index 07e971599..6fd8d38cc 100644 --- a/api.go +++ b/api.go @@ -834,6 +834,15 @@ func (api *API) FragmentData(ctx context.Context, indexName, fieldName, viewName return f, nil } +type RedirectError struct { + HostPort string + error string +} + +func (r RedirectError) Error() string { + return r.error +} + // TranslateData returns all translation data in the specified partition. func (api *API) TranslateData(ctx context.Context, indexName string, partition int) (io.WriterTo, error) { span, _ := tracing.StartSpanFromContext(ctx, "API.TranslateData") @@ -849,6 +858,15 @@ func (api *API) TranslateData(ctx context.Context, indexName string, partition i return nil, newNotFoundError(ErrIndexNotFound, indexName) } + snap := topology.NewClusterSnapshot(api.cluster.noder, api.cluster.Hasher, api.cluster.ReplicaN) + nodes := snap.PartitionNodes(partition) + if nodes[0].ID != api.server.NodeID() { + return nil, RedirectError{ + HostPort: nodes[0].URI.HostPort(), + error: fmt.Sprintf("can't translate data, this node(%s) does not partition %d", api.server.uri, partition), + } + } + // Retrieve translatestore from holder. store := idx.TranslateStore(partition) if store == nil { diff --git a/http/handler.go b/http/handler.go index 94665bbfa..9e626babf 100644 --- a/http/handler.go +++ b/http/handler.go @@ -2326,6 +2326,12 @@ func (h *Handler) handleGetTranslateData(w http.ResponseWriter, r *http.Request) // Retrieve partition data from holder. p, err := h.api.TranslateData(r.Context(), q.Get("index"), int(partition)) + if redir, ok := err.(pilosa.RedirectError); ok { + newURL := *r.URL + newURL.Host = redir.HostPort + http.Redirect(w, r, newURL.String(), http.StatusSeeOther) + return + } if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return