redirect GetTranslateData if node doesn't own partition

This commit is contained in:
Matthew Jaffee 2021-12-06 10:36:55 -06:00
parent b8da3bc7e6
commit 7a8f0135b3
2 changed files with 24 additions and 0 deletions

18
api.go
View file

@ -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 {

View file

@ -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