func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if h.Shutdown.Load().(bool) { hh.ServiceUnavailableError(w, "discoverd: shutting down") return } // If running in proxy mode then redirect requests to a random peer if h.Proxy.Load().(bool) { if !proxyWhitelisted(r) { // TODO(jpg): Should configuring the peer in proxy mode with no peers be impossible? host := h.Peers[rand.Intn(len(h.Peers))] redirectToHost(w, r, host) return } } else { // Send current peer list and index to the client so it can keep the list of // peers in sync with the cluster. peers, err := h.Store.GetPeers() if err == nil { w.Header().Set("Discoverd-Peers", strings.Join(peers, ",")) } w.Header().Set("Discoverd-Index", strconv.FormatUint(h.Store.LastIndex(), 10)) } h.Handler.ServeHTTP(w, r) return }
// serveGetRaftLeader returns the current raft leader. func (h *Handler) serveGetRaftLeader(w http.ResponseWriter, r *http.Request, params httprouter.Params) { leader := h.Store.Leader() if leader == "" { hh.ServiceUnavailableError(w, ErrNoKnownLeader.Error()) return } hh.JSON(w, 200, dt.RaftLeader{Host: h.Store.Leader()}) }
// redirectToLeader redirects the request to the current known leader. func (h *Handler) redirectToLeader(w http.ResponseWriter, r *http.Request) { // Find the current leader. leader := h.Store.Leader() if leader == "" { hh.ServiceUnavailableError(w, ErrNoKnownLeader.Error()) return } redirectToHost(w, r, leader) }
func (api *HTTPAPI) Pull(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { cluster := api.cluster.Load().(*cluster.Client) if cluster == nil { httphelper.ServiceUnavailableError(w, "cluster client is not configured") return } volumeID := ps.ByName("volume_id") pull := &volume.PullCoordinate{} if err := httphelper.DecodeJSON(r, &pull); err != nil { httphelper.Error(w, err) return } hostClient, err := cluster.Host(pull.HostID) if err != nil { httphelper.Error(w, err) return } haves, err := api.vman.ListHaves(volumeID) if err != nil { httphelper.Error(w, err) return } reader, err := hostClient.SendSnapshot(pull.SnapshotID, haves) if err != nil { httphelper.Error(w, err) return } snap, err := api.vman.ReceiveSnapshot(volumeID, reader) if err != nil { httphelper.Error(w, err) return } httphelper.JSON(w, 200, snap.Info()) }