func (h *reqHandler) lazilyRespond(start, end uint64) {
	partSize := h.Cache.Storage.PartSize()
	indexes := utils.BreakInIndexes(h.objID, start, end, partSize)
	startOffset := start % partSize
	var shouldReturn = false

	for i := 0; i < len(indexes); {
		contents, partsCount, err := h.getContents(indexes, i)
		if err != nil {
			h.Logger.Errorf("[%p] Unexpected error while trying to load %s from storage: %s", h.req, indexes[i], err)
			return
		}
		if i == 0 && startOffset > 0 {
			contents, err = utils.SkipReadCloser(contents, int64(startOffset))
			if err != nil {
				h.Logger.Errorf("[%p] Unexpected error while trying to skip %d from %s : %s", h.req, startOffset, indexes[i], err)
				return
			}
		}
		if i+partsCount == len(indexes) {
			endLimit := uint64(partsCount-1)*partSize + end%partSize + 1
			if i == 0 {
				endLimit -= startOffset
			}
			contents = utils.LimitReadCloser(contents, int64(endLimit)) //!TODO: fix int conversion
		}

		if copied, err := io.Copy(h.resp, contents); err != nil {
			h.Logger.Logf("[%p] Error sending contents after %d bytes of %s, parts[%d-%d]: %s",
				h.req, copied, h.objID, i, i+partsCount-1, err)

			shouldReturn = true
		}
		//!TODO: compare the copied length with the expected

		if err := contents.Close(); err != nil {
			h.Logger.Errorf("[%p] Unexpected error while closing content reader for %s, parts[%d-%d]: %s",
				h.req, h.objID, i, i+partsCount-1, err)
		}

		if shouldReturn {
			return
		}

		i += partsCount
	}
}
Esempio n. 2
0
func checkParts(t *testing.T, start, length uint64, cz *types.CacheZone, oid *types.ObjectID) {
	partSize := cz.Storage.PartSize()
	indexes := utils.BreakInIndexes(oid, start, start+length-1, partSize)
	prefix := fmt.Sprintf("[PartWriter(%d,%d),Storage(%d)]", start, length, partSize)

	if len(indexes) > 0 && start%partSize != 0 {
		checkPartIsMissing(t, prefix+"first part", cz.Storage, indexes[0])
		indexes = indexes[1:]
	}
	if len(indexes) > 0 && (start+length)%partSize != 0 && (start+length) != inputSize {
		checkPartIsMissing(t, prefix+"last part", cz.Storage, indexes[len(indexes)-1])
		indexes = indexes[:len(indexes)-1]
	}
	for _, idx := range indexes {
		partNum := uint64(idx.Part)
		expected := input[partSize*partNum : umin(inputSize, (partNum+1)*partSize)]
		checkPart(t, fmt.Sprintf("%s part %d", prefix, partNum), expected, cz.Storage, idx)
	}
}