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

     1  package bidstrategy
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math"
     7  	"strconv"
     8  	"time"
     9  
    10  	"github.com/filecoin-project/bacalhau/pkg/model"
    11  )
    12  
    13  type TimeoutStrategyParams struct {
    14  	MaxJobExecutionTimeout time.Duration
    15  	MinJobExecutionTimeout time.Duration
    16  
    17  	JobExecutionTimeoutClientIDBypassList []string
    18  }
    19  
    20  type TimeoutStrategy struct {
    21  	maxJobExecutionTimeout                time.Duration
    22  	minJobExecutionTimeout                time.Duration
    23  	jobExecutionTimeoutClientIDBypassList []string
    24  }
    25  
    26  func NewTimeoutStrategy(params TimeoutStrategyParams) *TimeoutStrategy {
    27  	return &TimeoutStrategy{
    28  		maxJobExecutionTimeout:                params.MaxJobExecutionTimeout,
    29  		minJobExecutionTimeout:                params.MinJobExecutionTimeout,
    30  		jobExecutionTimeoutClientIDBypassList: params.JobExecutionTimeoutClientIDBypassList,
    31  	}
    32  }
    33  
    34  func (s *TimeoutStrategy) ShouldBid(_ context.Context, request BidStrategyRequest) (BidStrategyResponse, error) {
    35  	if request.Job.Spec.Timeout <= 0 {
    36  		return newShouldBidResponse(), nil
    37  	}
    38  
    39  	// Timeout will be multiplied by 1000000000 (time.Second) when it gets converted to a time.Duration (which is an int64 underneath),
    40  	// so make sure that iit can fit into it.
    41  	if request.Job.Spec.Timeout > float64(math.MaxInt64/int64(time.Second)) {
    42  		timeout := strconv.FormatFloat(request.Job.Spec.Timeout, 'f', -1, sixtyFourBitFloat)
    43  		return BidStrategyResponse{
    44  			ShouldBid: false,
    45  			Reason:    fmt.Sprintf("job timeout %s exceeds maximum possible value", timeout),
    46  		}, nil
    47  	}
    48  
    49  	for _, clientID := range s.jobExecutionTimeoutClientIDBypassList {
    50  		if request.Job.Metadata.ClientID == clientID {
    51  			return newShouldBidResponse(), nil
    52  		}
    53  	}
    54  
    55  	// skip bidding if the job spec defined a timeout value higher or lower than what we are willing to accept
    56  	if s.maxJobExecutionTimeout > 0 && request.Job.Spec.GetTimeout() > s.maxJobExecutionTimeout {
    57  		return BidStrategyResponse{
    58  			ShouldBid: false,
    59  			Reason:    fmt.Sprintf("job timeout %s exceeds maximum allowed %s", request.Job.Spec.GetTimeout(), s.maxJobExecutionTimeout),
    60  		}, nil
    61  	}
    62  	if request.Job.Spec.GetTimeout() < s.minJobExecutionTimeout {
    63  		return BidStrategyResponse{
    64  			ShouldBid: false,
    65  			Reason:    fmt.Sprintf("job timeout %s below minimum allowed %s", request.Job.Spec.GetTimeout(), s.minJobExecutionTimeout),
    66  		}, nil
    67  	}
    68  	return newShouldBidResponse(), nil
    69  }
    70  
    71  func (s *TimeoutStrategy) ShouldBidBasedOnUsage(context.Context, BidStrategyRequest, model.ResourceUsageData) (BidStrategyResponse, error) {
    72  	return newShouldBidResponse(), nil
    73  }
    74  
    75  const sixtyFourBitFloat = 64