github.com/filecoin-project/bacalhau@v0.3.23-0.20230228154132-45c989550ace/pkg/compute/store/resolver/resolver.go (about)

     1  package resolver
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/filecoin-project/bacalhau/pkg/compute/store"
     9  	"github.com/filecoin-project/bacalhau/pkg/system"
    10  )
    11  
    12  var DefaultStateResolverParams = StateResolverParams{
    13  	MaxWaitAttempts: 500, // 10 seconds total wait time
    14  	WaitDelay:       20 * time.Millisecond,
    15  }
    16  
    17  type StateResolverParams struct {
    18  	ExecutionStore  store.ExecutionStore
    19  	MaxWaitAttempts int
    20  	WaitDelay       time.Duration
    21  }
    22  type StateResolver struct {
    23  	executionStore  store.ExecutionStore
    24  	maxWaitAttempts int
    25  	waitDelay       time.Duration
    26  }
    27  
    28  func NewStateResolver(params StateResolverParams) *StateResolver {
    29  	if params.MaxWaitAttempts == 0 {
    30  		params.MaxWaitAttempts = DefaultStateResolverParams.MaxWaitAttempts
    31  	}
    32  	if params.WaitDelay == 0 {
    33  		params.WaitDelay = DefaultStateResolverParams.WaitDelay
    34  	}
    35  	return &StateResolver{
    36  		executionStore:  params.ExecutionStore,
    37  		maxWaitAttempts: params.MaxWaitAttempts,
    38  		waitDelay:       params.WaitDelay,
    39  	}
    40  }
    41  
    42  func (r *StateResolver) Wait(
    43  	ctx context.Context,
    44  	executionID string,
    45  	checkStateFunctions ...CheckStateFunction) error {
    46  	waiter := &system.FunctionWaiter{
    47  		Name:        "Wait for execution state",
    48  		MaxAttempts: r.maxWaitAttempts,
    49  		Delay:       r.waitDelay,
    50  		Handler: func() (bool, error) {
    51  			execution, err := r.executionStore.GetExecution(ctx, executionID)
    52  			if err != nil {
    53  				return false, err
    54  			}
    55  
    56  			allOK := true
    57  			for _, checkFunction := range checkStateFunctions {
    58  				stepOK, stepErr := checkFunction(execution)
    59  				if stepErr != nil {
    60  					return false, stepErr
    61  				}
    62  				allOK = allOK && stepOK
    63  			}
    64  
    65  			if allOK {
    66  				return true, nil
    67  			}
    68  
    69  			allTerminal, err := CheckForTerminalStates()(execution)
    70  			if err != nil {
    71  				return false, err
    72  			}
    73  			if allTerminal {
    74  				return false, fmt.Errorf(
    75  					"execution reached a terminal state before meeting the resolver's conditions: %s", execution)
    76  			}
    77  			return false, nil
    78  		},
    79  	}
    80  	return waiter.Wait(ctx)
    81  }