func (r *Remote) UpsertByComparison(args *upsertOpt) (f *File, err error) { /* // TODO: (@odeke-em) decide: // + if to reject FIFO // + perform an assertion for fileStated.IsDir() == args.src.IsDir */ if args.src == nil { err = fmt.Errorf("bug on: src cannot be nil") return } var body io.Reader if !args.src.IsDir { body, err = os.Open(args.fsAbsPath) if err != nil { return } } bd := statos.NewReader(body) go func() { commChan := bd.ProgressChan() for n := range commChan { r.progressChan <- n } }() mediaInserted := false f, mediaInserted, err = r.upsertByComparison(bd, args) // Case in which for example just Chtime-ing if !mediaInserted && args.dest != nil { chunks := chunkInt64(args.dest.Size) for n := range chunks { r.progressChan <- n } } return }
func (r *Remote) UpsertByComparison(args *upsertOpt) (f *File, err error) { /* // TODO: (@odeke-em) decide: // + if to reject FIFO // + perform an assertion for fileStated.IsDir() == args.src.IsDir */ if args.src == nil { err = fmt.Errorf("bug on: src cannot be nil") return } var body io.Reader if !args.src.IsDir { body, err = os.Open(args.fsAbsPath) if err != nil { return } } bd := statos.NewReader(body) go func() { commChan := bd.ProgressChan() for n := range commChan { r.progressChan <- n } }() resultLoad := make(chan *tuple) go func() { emitter := func() (interface{}, error) { f, mediaInserted, err := r.upsertByComparison(bd, args) return &tuple{first: f, second: mediaInserted, last: err}, err } retrier := retryableChangeOp(emitter, args.debug) res, err := expb.ExponentialBackOffSync(retrier) resultLoad <- &tuple{first: res, last: err} }() result := <-resultLoad if result == nil { return f, err } tup, tupOk := result.first.(*tuple) if tupOk { ff, fOk := tup.first.(*File) if fOk { f = ff } mediaInserted, mediaOk := tup.second.(bool) // Case in which for example just Chtime-ing if mediaOk && !mediaInserted && f != nil { chunks := chunkInt64(f.Size) for n := range chunks { r.progressChan <- n } } errV, errCastOk := tup.last.(error) if errCastOk { err = errV } } return f, err }
func (r *Remote) UpsertByComparison(args *upsertOpt) (f *File, err error) { /* // TODO: (@odeke-em) decide: // + if to reject FIFO // + perform an assertion for fileStated.IsDir() == args.src.IsDir */ if args.src == nil { err = illogicalStateErr(fmt.Errorf("bug on: src cannot be nil")) return } var body io.Reader var cleanUp func() error if !args.src.IsDir { // In relation to issue #612, since we are not only resolving // relative to the current working directory, we should try reading // first from the source's original local fsAbsPath aka `BlobAt` // because the resolved path might be different from the original path. fsAbsPath := args.src.BlobAt if fsAbsPath == "" { fsAbsPath = args.fsAbsPath } if args.shouldUploadBody() { file, err := os.Open(fsAbsPath) if err != nil { return nil, err } // We need to make sure that we close all open handles. // See Issue https://github.com/odeke-em/drive/issues/711. cleanUp = file.Close body = file } } bd := statos.NewReader(body) go func() { commChan := bd.ProgressChan() for n := range commChan { r.progressChan <- n } }() resultLoad := make(chan *tuple) go func() { if cleanUp != nil { defer cleanUp() } emitter := func() (interface{}, error) { f, mediaInserted, err := r.upsertByComparison(bd, args) return &tuple{first: f, second: mediaInserted, last: err}, err } retrier := retryableChangeOp(emitter, args.debug, args.retryCount) res, err := expb.ExponentialBackOffSync(retrier) resultLoad <- &tuple{first: res, last: err} }() result := <-resultLoad if result == nil { return f, err } tup, tupOk := result.first.(*tuple) if tupOk { ff, fOk := tup.first.(*File) if fOk { f = ff } mediaInserted, mediaOk := tup.second.(bool) // Case in which for example just Chtime-ing if mediaOk && !mediaInserted && f != nil { chunks := chunkInt64(f.Size) for n := range chunks { r.progressChan <- n } } errV, errCastOk := tup.last.(error) if errCastOk { err = errV } } return f, err }