@@ -232,7 +232,7 @@ func (s Sync) Run(c *cli.Context) error {
232232 pipeReader , pipeWriter := io .Pipe () // create a reader, writer pipe to pass commands to run
233233
234234 // Create commands in background.
235- go s .planRun (c , onlySource , onlyDest , commonObjects , dsturl , strategy , pipeWriter , isBatch )
235+ go s .planRun (ctx , c , onlySource , onlyDest , commonObjects , dsturl , strategy , pipeWriter , isBatch )
236236
237237 err = NewRun (c , pipeReader ).Run (ctx )
238238 return multierror .Append (err , merrorWaiter ).ErrorOrNil ()
@@ -434,6 +434,7 @@ func (s Sync) getSourceAndDestinationObjects(ctx context.Context, cancel context
434434
435435// planRun prepares the commands and writes them to writer 'w'.
436436func (s Sync ) planRun (
437+ ctx context.Context ,
437438 c * cli.Context ,
438439 onlySource , onlyDest chan * url.URL ,
439440 common chan * ObjectPair ,
@@ -459,36 +460,58 @@ func (s Sync) planRun(
459460 wg .Add (1 )
460461 go func () {
461462 defer wg .Done ()
462- for srcurl := range onlySource {
463- curDestURL := generateDestinationURL (srcurl , dsturl , isBatch )
464- command , err := generateCommand (c , "cp" , defaultFlags , srcurl , curDestURL )
465- if err != nil {
466- printDebug (s .op , err , srcurl , curDestURL )
467- continue
463+ for {
464+ select {
465+ case srcurl := <- onlySource :
466+ if srcurl == nil {
467+ return
468+ }
469+ curDestURL := generateDestinationURL (srcurl , dsturl , isBatch )
470+ command , err := generateCommand (c , "cp" , defaultFlags , srcurl , curDestURL )
471+ if err != nil {
472+ printDebug (s .op , err , srcurl , curDestURL )
473+ continue
474+ }
475+ fmt .Fprintln (w , command )
476+ case <- ctx .Done ():
477+ // If the context was cancelled, there was an error.
478+ if err := ctx .Err (); err != nil {
479+ return
480+ }
468481 }
469- fmt .Fprintln (w , command )
470482 }
471483 }()
472484
473485 // both in source and destination
474486 wg .Add (1 )
475487 go func () {
476488 defer wg .Done ()
477- for commonObject := range common {
478- sourceObject , destObject := commonObject .src , commonObject .dst
479- curSourceURL , curDestURL := sourceObject .URL , destObject .URL
480- err := strategy .ShouldSync (sourceObject , destObject ) // check if object should be copied.
481- if err != nil {
482- printDebug (s .op , err , curSourceURL , curDestURL )
483- continue
484- }
489+ for {
490+ select {
491+ case commonObject := <- common :
492+ if commonObject == nil {
493+ return
494+ }
495+ sourceObject , destObject := commonObject .src , commonObject .dst
496+ curSourceURL , curDestURL := sourceObject .URL , destObject .URL
497+ err := strategy .ShouldSync (sourceObject , destObject ) // check if object should be copied.
498+ if err != nil {
499+ printDebug (s .op , err , curSourceURL , curDestURL )
500+ continue
501+ }
485502
486- command , err := generateCommand (c , "cp" , defaultFlags , curSourceURL , curDestURL )
487- if err != nil {
488- printDebug (s .op , err , curSourceURL , curDestURL )
489- continue
503+ command , err := generateCommand (c , "cp" , defaultFlags , curSourceURL , curDestURL )
504+ if err != nil {
505+ printDebug (s .op , err , curSourceURL , curDestURL )
506+ continue
507+ }
508+ fmt .Fprintln (w , command )
509+ case <- ctx .Done ():
510+ // If the context was cancelled, there was an error.
511+ if err := ctx .Err (); err != nil {
512+ return
513+ }
490514 }
491- fmt .Fprintln (w , command )
492515 }
493516 }()
494517
@@ -501,8 +524,21 @@ func (s Sync) planRun(
501524 // or rewrite generateCommand function?
502525 dstURLs := make ([]* url.URL , 0 , extsortChunkSize )
503526
504- for d := range onlyDest {
505- dstURLs = append (dstURLs , d )
527+ finished := false
528+ for ! finished {
529+ select {
530+ case d := <- onlyDest :
531+ if d == nil {
532+ finished = true
533+ break
534+ }
535+ dstURLs = append (dstURLs , d )
536+ case <- ctx .Done ():
537+ // If the context was cancelled, there was an error.
538+ if err := ctx .Err (); err != nil {
539+ return
540+ }
541+ }
506542 }
507543
508544 if len (dstURLs ) == 0 {
@@ -576,7 +612,7 @@ func (s Sync) shouldStopSync(err error) bool {
576612 }
577613 if awsErr , ok := err .(awserr.Error ); ok {
578614 switch awsErr .Code () {
579- case "AccessDenied" , "NoSuchBucket" :
615+ case "AccessDenied" , "NoSuchBucket" , "RequestError" , "SerializationError" :
580616 return true
581617 }
582618 }
0 commit comments