github.com/release-engineering/exodus-rsync@v1.11.2/internal/gw/task.go (about) 1 package gw 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/release-engineering/exodus-rsync/internal/log" 9 ) 10 11 type task struct { 12 client *client 13 raw struct { 14 ID string 15 PublishID string 16 State string 17 Links map[string]string 18 } 19 } 20 21 func (t *task) refresh(ctx context.Context) error { 22 logger := log.FromContext(ctx) 23 24 url, ok := t.raw.Links["self"] 25 if !ok { 26 return fmt.Errorf("task object is missing 'self' link: %+v", *t) 27 } 28 29 logger.F("url", url).Debug("polling task") 30 31 return t.client.doJSONRequest(ctx, "GET", url, nil, &t.raw, nil) 32 } 33 34 func (t *task) ID() string { 35 return t.raw.ID 36 } 37 38 func (t *task) Await(ctx context.Context) error { 39 logger := log.FromContext(ctx) 40 pollDuration := time.Millisecond * time.Duration(t.client.cfg.GwPollInterval()) 41 42 for { 43 if t.raw.State == "COMPLETE" { 44 // succeeded 45 logger.F("task", t.ID()).Info("Task completed") 46 return nil 47 } 48 49 if t.raw.State == "FAILED" { 50 logger.F("task", t.raw.ID).Info("Task failed") 51 return fmt.Errorf("publish task %s failed", t.raw.ID) 52 } 53 54 // Not in a terminal state - query it again soon 55 select { 56 case <-ctx.Done(): 57 return ctx.Err() 58 case <-time.After(pollDuration): 59 } 60 61 if err := t.refresh(ctx); err != nil { 62 return fmt.Errorf("polling task %v: %w", t.raw.ID, err) 63 } 64 } 65 }