Example #1
0
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
}
Example #2
0
// 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()})
}
Example #3
0
// 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)
}
Example #4
0
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())
}