// finishUploadIfComplete checks whether an upload is completed (i.e. upload offset
// matches upload size) and if so, it will call the data store's FinishUpload
// function and send the necessary message on the CompleteUpload channel.
764022
func (handler *UnroutedHandler) finishUploadIfComplete(info FileInfo) error {
	// If the upload is completed, ...
	if !info.SizeIsDeferred && info.Offset == info.Size {
		// ... allow custom mechanism to finish and cleanup the upload
		if handler.composer.UsesFinisher {
			if err := handler.composer.Finisher.FinishUpload(info.ID); err != nil {
				return err
			}
		}

		// ... send the info out to the channel
		if handler.config.NotifyCompleteUploads {
			handler.CompleteUploads <- info
		}

		handler.Metrics.incUploadsFinished()
	}

	return nil
}
1320608
func (l *gcsGateway) AbortMultipartUpload(ctx context.Context, bucket string, key string, uploadID string) error {
	if err := l.checkUploadIDExists(ctx, bucket, key, uploadID); err != nil {
		return err
	}
	return l.cleanupMultipartUpload(ctx, bucket, key, uploadID)
}
1203610
func (m *Method) FinalFunc(f FinalFunc) *Method {
	m.finalFuncs = append(m.finalFuncs, f)
	return m
}
573695
func (s *TasksGetTaskService) WaitForCompletion(waitForCompletion bool) *TasksGetTaskService {
	s.waitForCompletion = &waitForCompletion
	return s
}
1054583
func AsCompleted(fs ...*F) <-chan *F {
	ret := make(chan *F, len(fs))
	var wg sync.WaitGroup
	for _, f := range fs {
		wg.Add(1)
		go func(f *F) {
			defer wg.Done()
			<-f.Done()
			ret <- f
		}(f)
	}
	go func() {
		wg.Wait()
		close(ret)
	}()
	return ret
}
107044
func (s *storageImpl) finishAndForcedHash(c context.Context, op *upload.Operation, hash *api.ObjectRef) (*upload.Operation, error) {
	gs := s.getGS(c)
	cfg, err := s.settings(c)
	if err != nil {
		return nil, err
	}

	// Try to move the object into the final location. This may fail
	// transiently, in which case we ask the client to retry, or fatally, in
	// which case we close the upload operation with an error.
	pubErr := gs.Publish(c, cfg.ObjectPath(hash), op.TempGSPath, -1)
	if transient.Tag.In(pubErr) {
		return nil, errors.Annotate(pubErr, "failed to publish the object").
			Tag(grpcutil.InternalTag).Err()
	}

	// Try to remove the leftover garbage. See maybeDelete doc for possible
	// caveats.
	if err := s.maybeDelete(c, gs, op.TempGSPath); err != nil {
		return nil, err
	}

	// Set the status of the operation based on whether we published the file
	// or not.
	return op.Advance(c, func(_ context.Context, op *upload.Operation) error {
		if pubErr != nil {
			op.Status = api.UploadStatus_ERRORED
			op.Error = fmt.Sprintf("Failed to publish the object - %s", pubErr)
		} else {
			op.Status = api.UploadStatus_PUBLISHED
			op.HashAlgo = hash.HashAlgo
			op.HexDigest = hash.HexDigest
		}
		return nil
	})
}
907865
func (aw *AnsiWriter) finish(parse func([]byte) error) error {
	var err error

	if parse != nil {
		err = parse(aw.buf[2:])
	}

	aw.buf = nil
	return err
}
1248903
func (m *Multi) Complete(parts []Part) error {
	params := make(url.Values)
	params.Set("uploadId", m.UploadId)

	c := completeUpload{}
	for _, p := range parts {
		c.Parts = append(c.Parts, completePart{p.N, p.ETag})
	}
	sort.Sort(c.Parts)
	data, err := xml.Marshal(&c)
	if err != nil {
		return err
	}
	for attempt := attempts.Start(); attempt.Next(); {
		req := &request{
			method:  "POST",
			bucket:  m.Bucket.Name,
			path:    m.Key,
			params:  params,
			payload: bytes.NewReader(data),
		}
		err := m.Bucket.Client.query(req, nil)
		if shouldRetry(err) && attempt.HasNext() {
			continue
		}
		return err
	}
	panic("unreachable")
}
999717
func (pb *ProgressBar) IsFinished() bool {
	pb.mu.Lock()
	defer pb.mu.Unlock()
	return pb.isFinish
}
124704
func (s *Rule) SetAbortIncompleteMultipartUpload(v *AbortIncompleteMultipartUpload) *Rule {
	s.AbortIncompleteMultipartUpload = v
	return s
}
60555
func (c *Client) ensureRequestComplete(ctx context.Context, resp *http.Response) {
	if resp == nil {
		return
	}

	defer resp.Body.Close()
	io.Copy(ioutil.Discard, resp.Body)
}
1047689
func (g *Generation) CheckNotComplete() error {
	if g.doc.Completed == 0 {
		return nil
	}

	msg := "committed"
	if g.doc.GenerationId == 0 {
		msg = "aborted"
	}
	return errors.New("branch was already " + msg)
}
826602
func (s *LifecycleRule) SetAbortIncompleteMultipartUpload(v *AbortIncompleteMultipartUpload) *LifecycleRule {
	s.AbortIncompleteMultipartUpload = v
	return s
}
954155
func (ru *resumableUpload) Close() error {
	if err := ru.checkError(); err != nil {
		return err
	}

	if ru.closed {
		return nil
	}
	ru.closed = true

	// flush!
	data := ru.splitBuf.Bytes()
	ru.blocks <- &rblock{
		data: append([]byte{}, data...),
	}
	close(ru.blocks)

	// wait for work() to be done
	select {
	case <-ru.done: // muffin
	case <-ru.pushedErr: // muffin
	}

	// return any errors
	return ru.checkError()
}
1209513
func (m *Multi) Complete(parts []Part) error {
	params := map[string][]string{
		"uploadId": {m.UploadId},
	}
	c := completeUpload{}
	for _, p := range parts {
		c.Parts = append(c.Parts, completePart{p.N, p.ETag})
	}
	sort.Sort(c.Parts)
	data, err := xml.Marshal(&c)
	if err != nil {
		return err
	}
	for attempt := attempts.Start(); attempt.Next(); {
		req := &request{
			method:  "POST",
			bucket:  m.Bucket.Name,
			path:    m.Key,
			params:  params,
			payload: bytes.NewReader(data),
		}
		var resp completeUploadResp
		if m.Bucket.Region.Name == "generic" {
			headers := make(http.Header)
			headers.Add("Content-Length", strconv.FormatInt(int64(len(data)), 10))
			req.headers = headers
		}
		err := m.Bucket.KS3.query(req, &resp)
		if shouldRetry(err) && attempt.HasNext() {
			continue
		}

		if err != nil {
			return err
		}

		// A 200 error code does not guarantee that there were no errors,
		// so first figure out what kind of XML "object" we are dealing with.

		if resp.XMLName.Local == "Error" {
			// KS3.query does the unmarshalling for us, so we can't unmarshal
			// again in a different struct... So we need to duct-tape back the
			// original XML back together.
			fullErrorXml := "<Error>" + resp.InnerXML + "</Error>"
			ks3err := &Error{}

			if err := xml.Unmarshal([]byte(fullErrorXml), ks3err); err != nil {
				return err
			}

			return ks3err
		}

		if resp.XMLName.Local == "CompleteMultipartUploadResult" {
			// One could probably add a CompleteFull method returning the
			// actual contents of the CompleteMultipartUploadResult object.
			return nil
		}

		return errors.New("Invalid XML struct returned: " + resp.XMLName.Local)
	}
	panic("unreachable")
}
1256696
func (a GatewayUnsupported) AbortMultipartUpload(ctx context.Context, bucket string, object string, uploadID string) error {
	return NotImplemented{}
}
296155
func (r *ForwarderRequest) Complete(sendReset bool) {
	r.mu.Lock()
	defer r.mu.Unlock()

	if r.segment == nil {
		panic("Completing already completed forwarder request")
	}

	// Remove request from the forwarder.
	r.forwarder.mu.Lock()
	delete(r.forwarder.inFlight, r.segment.id)
	r.forwarder.mu.Unlock()

	// If the caller requested, send a reset.
	if sendReset {
		replyWithReset(r.segment)
	}

	// Release all resources.
	r.segment.decRef()
	r.segment = nil
	r.forwarder = nil
}