Skip to content

Commit 50823ce

Browse files
committed
Improve sync error handling
1 parent c1c7ee3 commit 50823ce

File tree

1 file changed

+60
-24
lines changed

1 file changed

+60
-24
lines changed

command/sync.go

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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'.
436436
func (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

Comments
 (0)