|
| 1 | +// Package strategy is a strategy pattern wrapper around the store implementations |
| 2 | +// |
| 3 | +// NOTE: this may be refactored out into the store package directly |
1 | 4 | package strategy |
2 | 5 |
|
3 | 6 | import ( |
4 | 7 | "context" |
5 | 8 | "errors" |
6 | 9 | "fmt" |
| 10 | + "sync" |
7 | 11 |
|
8 | 12 | "github.com/DevLabFoundry/configmanager/v2/internal/config" |
9 | 13 | "github.com/DevLabFoundry/configmanager/v2/internal/log" |
@@ -44,32 +48,43 @@ func defaultStrategyFuncMap(logger log.ILogger) map[config.ImplementationPrefix] |
44 | 48 | } |
45 | 49 | } |
46 | 50 |
|
| 51 | +type strategyFnMap struct { |
| 52 | + mu sync.Mutex |
| 53 | + funcMap StrategyFuncMap |
| 54 | +} |
47 | 55 | type RetrieveStrategy struct { |
48 | 56 | implementation store.Strategy |
49 | 57 | config config.GenVarsConfig |
50 | | - strategyFuncMap StrategyFuncMap |
51 | | - token string |
| 58 | + strategyFuncMap strategyFnMap |
52 | 59 | } |
| 60 | +type Opts func(*RetrieveStrategy) |
53 | 61 |
|
54 | 62 | // New |
55 | | -func New(s store.Strategy, config config.GenVarsConfig, logger log.ILogger) *RetrieveStrategy { |
| 63 | +func New(config config.GenVarsConfig, logger log.ILogger, opts ...Opts) *RetrieveStrategy { |
56 | 64 | rs := &RetrieveStrategy{ |
57 | | - implementation: s, |
58 | 65 | config: config, |
59 | | - strategyFuncMap: defaultStrategyFuncMap(logger), |
| 66 | + strategyFuncMap: strategyFnMap{mu: sync.Mutex{}, funcMap: defaultStrategyFuncMap(logger)}, |
| 67 | + } |
| 68 | + // overwrite or add any options/defaults set above |
| 69 | + for _, o := range opts { |
| 70 | + o(rs) |
60 | 71 | } |
| 72 | + |
61 | 73 | return rs |
62 | 74 | } |
63 | 75 |
|
64 | 76 | // WithStrategyFuncMap Adds custom implementations for prefix |
65 | 77 | // |
66 | 78 | // Mainly used for testing |
67 | 79 | // NOTE: this may lead to eventual optional configurations by users |
68 | | -func (rs *RetrieveStrategy) WithStrategyFuncMap(funcMap StrategyFuncMap) *RetrieveStrategy { |
69 | | - for prefix, implementation := range funcMap { |
70 | | - rs.strategyFuncMap[config.ImplementationPrefix(prefix)] = implementation |
| 80 | +func WithStrategyFuncMap(funcMap StrategyFuncMap) Opts { |
| 81 | + return func(rs *RetrieveStrategy) { |
| 82 | + for prefix, implementation := range funcMap { |
| 83 | + rs.strategyFuncMap.mu.Lock() |
| 84 | + defer rs.strategyFuncMap.mu.Unlock() |
| 85 | + rs.strategyFuncMap.funcMap[config.ImplementationPrefix(prefix)] = implementation |
| 86 | + } |
71 | 87 | } |
72 | | - return rs |
73 | 88 | } |
74 | 89 |
|
75 | 90 | func (rs *RetrieveStrategy) setImplementation(strategy store.Strategy) { |
@@ -120,7 +135,7 @@ func (rs *RetrieveStrategy) SelectImplementation(ctx context.Context, token *con |
120 | 135 | return nil, fmt.Errorf("unable to get prefix, %w", ErrTokenInvalid) |
121 | 136 | } |
122 | 137 |
|
123 | | - if store, found := rs.strategyFuncMap[token.Prefix()]; found { |
| 138 | + if store, found := rs.strategyFuncMap.funcMap[token.Prefix()]; found { |
124 | 139 | return store(ctx, token) |
125 | 140 | } |
126 | 141 |
|
|
0 commit comments