Esempio n. 1
0
func (m *Multi) Get(key string, opts store.GetOptions) ([]byte, store.Stat, error) {
	r := retry.New(10)
	for r.Next() {
		f, err := m.getFile(key)
		if err != nil {
			return nil, store.Stat{}, err
		}

		if f == nil {
			return nil, store.Stat{}, store.ErrNotFound
		}

		data, err := m.reconstruct(f, opts)
		if err != nil {
			f2, err2 := m.getFile(key)
			if err2 != nil {
				return nil, store.Stat{}, err2
			}
			if f2 == nil || f2.PrefixID != f.PrefixID {
				// someone wrote to this file and removed some pieces as we
				// were reading it; retry the read.
				continue
			}
			return nil, store.Stat{}, err
		}

		return data, store.Stat{
			SHA256:    f.SHA256,
			Size:      int64(f.Size),
			WriteTime: f.WriteTime,
		}, err
	}

	return nil, store.Stat{}, ErrTooManyRetries
}
Esempio n. 2
0
func (h *Server) serveObjectDelete(w http.ResponseWriter, r *http.Request, obj string) {
	canceller := makeCanceller(w)
	defer canceller.Close()

	doRetry := true
	retr := retry.New(10)
	for retr.Next() {
		doRetry = false

		from, err := parseIfMatch(r.Header.Get("If-Match"))
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		if from.Any {
			// TODO: make the CAS interface rich enough to handle this
			// without Stat
			st, err := h.store.Stat(obj, canceller.Cancel)
			if err != nil {
				if err == store.ErrNotFound {
					http.Error(w, "not found", http.StatusNotFound)
					return
				}
				log.Printf("Couldn't Stat(%#v): %v", obj, err)
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			from = store.CASV{Present: true, SHA256: st.SHA256}
			doRetry = true
		}

		err = h.store.CAS(obj, from, store.CASV{Present: false}, canceller.Cancel)
		if err != nil {
			if err == store.ErrCASFailure {
				if doRetry {
					continue
				} else {
					http.Error(w, err.Error(),
						http.StatusPreconditionFailed)
					return
				}
			}
			log.Printf("Couldn't CAS(%#v): %v", obj, err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		w.WriteHeader(http.StatusNoContent)
		return
	}

	http.Error(w, "too many retries", http.StatusInternalServerError)
}