// This file contains the implementation of the sync batcher for uploads // // Dropbox rules say you can start as many batches as you want, but // you may only have one batch being committed and must wait for the // batch to be finished before committing another. package dropbox import ( "context" "fmt" "github.com/dropbox/dropbox-sdk-go-unofficial/v6/dropbox/files" ) // finishBatch commits the batch, returning a batch status to poll or maybe complete func (f *Fs) finishBatch(ctx context.Context, items []*files.UploadSessionFinishArg) (complete *files.UploadSessionFinishBatchResult, err error) { var arg = &files.UploadSessionFinishBatchArg{ Entries: items, } err = f.pacer.Call(func() (bool, error) { complete, err = f.srv.UploadSessionFinishBatchV2(arg) if retry, err := shouldRetryExclude(ctx, err); !retry { return retry, err } // after the first chunk is uploaded, we retry everything except the excluded errors return err != nil, err }) if err != nil { return nil, fmt.Errorf("batch commit failed: %w", err) } return complete, nil } // Called by the batcher to commit a batch func (f *Fs) commitBatch(ctx context.Context, items []*files.UploadSessionFinishArg, results []*files.FileMetadata, errors []error) (err error) { // finalise the batch getting either a result or a job id to poll complete, err := f.finishBatch(ctx, items) if err != nil { return err } // Check we got the right number of entries entries := complete.Entries if len(entries) != len(results) { return fmt.Errorf("expecting %d items in batch but got %d", len(results), len(entries)) } // Format results for return for i := range results { item := entries[i] if item.Tag == "success" { results[i] = item.Success } else { errorTag := item.Tag if item.Failure != nil { errorTag = item.Failure.Tag if item.Failure.LookupFailed != nil { errorTag += "/" + item.Failure.LookupFailed.Tag } if item.Failure.Path != nil { errorTag += "/" + item.Failure.Path.Tag } if item.Failure.PropertiesError != nil { errorTag += "/" + item.Failure.PropertiesError.Tag } } errors[i] = fmt.Errorf("upload failed: %s", errorTag) } } return nil }