github.com/ethersphere/bee/v2@v2.2.0/pkg/file/redundancy/getter/strategies.go (about)

     1  // Copyright 2023 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package getter
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  	"time"
    11  
    12  	"github.com/ethersphere/bee/v2/pkg/log"
    13  	"github.com/ethersphere/bee/v2/pkg/retrieval"
    14  )
    15  
    16  const (
    17  	DefaultStrategy     = DATA                           // default prefetching strategy
    18  	DefaultStrict       = false                          // default fallback modes
    19  	DefaultFetchTimeout = retrieval.RetrieveChunkTimeout // timeout for each chunk retrieval
    20  )
    21  
    22  type (
    23  	strategyKey     struct{}
    24  	modeKey         struct{}
    25  	fetchTimeoutKey struct{}
    26  	loggerKey       struct{}
    27  	Strategy        = int
    28  )
    29  
    30  // Config is the configuration for the getter - public
    31  type Config struct {
    32  	Strategy     Strategy
    33  	Strict       bool
    34  	FetchTimeout time.Duration
    35  	Logger       log.Logger
    36  }
    37  
    38  const (
    39  	NONE Strategy = iota // no prefetching and no decoding
    40  	DATA                 // just retrieve data shards no decoding
    41  	PROX                 // proximity driven selective fetching
    42  	RACE                 // aggressive fetching racing all chunks
    43  	strategyCnt
    44  )
    45  
    46  // DefaultConfig is the default configuration for the getter
    47  var DefaultConfig = Config{
    48  	Strategy:     DefaultStrategy,
    49  	Strict:       DefaultStrict,
    50  	FetchTimeout: DefaultFetchTimeout,
    51  	Logger:       log.Noop,
    52  }
    53  
    54  // NewConfigFromContext returns a new Config based on the context
    55  func NewConfigFromContext(ctx context.Context, def Config) (conf Config, err error) {
    56  	var ok bool
    57  	conf = def
    58  	e := func(s string) error {
    59  		return fmt.Errorf("error setting %s from context", s)
    60  	}
    61  	if val := ctx.Value(strategyKey{}); val != nil {
    62  		conf.Strategy, ok = val.(Strategy)
    63  		if !ok {
    64  			return conf, e("strategy")
    65  		}
    66  	}
    67  	if val := ctx.Value(modeKey{}); val != nil {
    68  		conf.Strict, ok = val.(bool)
    69  		if !ok {
    70  			return conf, e("fallback mode")
    71  		}
    72  	}
    73  	if val := ctx.Value(fetchTimeoutKey{}); val != nil {
    74  		conf.FetchTimeout, ok = val.(time.Duration)
    75  		if !ok {
    76  			return conf, e("fetcher timeout")
    77  		}
    78  	}
    79  	if val := ctx.Value(loggerKey{}); val != nil {
    80  		conf.Logger, ok = val.(log.Logger)
    81  		if !ok {
    82  			return conf, e("strategy timeout")
    83  		}
    84  	}
    85  
    86  	return conf, nil
    87  }
    88  
    89  // SetStrategy sets the strategy for the retrieval
    90  func SetStrategy(ctx context.Context, s Strategy) context.Context {
    91  	return context.WithValue(ctx, strategyKey{}, s)
    92  }
    93  
    94  // SetStrict sets the strict mode for the retrieval
    95  func SetStrict(ctx context.Context, strict bool) context.Context {
    96  	return context.WithValue(ctx, modeKey{}, strict)
    97  }
    98  
    99  // SetFetchTimeout sets the timeout for each fetch
   100  func SetFetchTimeout(ctx context.Context, timeout time.Duration) context.Context {
   101  	return context.WithValue(ctx, fetchTimeoutKey{}, timeout)
   102  }
   103  
   104  func SetLogger(ctx context.Context, l log.Logger) context.Context {
   105  	return context.WithValue(ctx, loggerKey{}, l)
   106  }
   107  
   108  // SetConfigInContext sets the config params in the context
   109  func SetConfigInContext(ctx context.Context, s *Strategy, fallbackmode *bool, fetchTimeout *string, logger log.Logger) (context.Context, error) {
   110  	if s != nil {
   111  		ctx = SetStrategy(ctx, *s)
   112  	}
   113  
   114  	if fallbackmode != nil {
   115  		ctx = SetStrict(ctx, !(*fallbackmode))
   116  	}
   117  
   118  	if fetchTimeout != nil {
   119  		dur, err := time.ParseDuration(*fetchTimeout)
   120  		if err != nil {
   121  			return nil, err
   122  		}
   123  		ctx = SetFetchTimeout(ctx, dur)
   124  	}
   125  
   126  	if logger != nil {
   127  		ctx = SetLogger(ctx, logger)
   128  	}
   129  
   130  	return ctx, nil
   131  }