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  }