-
Notifications
You must be signed in to change notification settings - Fork 0
/
selector_config.go
148 lines (117 loc) · 3.53 KB
/
selector_config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package selector
import (
"log/slog"
"time"
"github.com/zalgonoise/cfg"
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/noop"
"github.com/zalgonoise/micron/executor"
"github.com/zalgonoise/micron/log"
"github.com/zalgonoise/micron/metrics"
)
type Config struct {
exec []executor.Executor
block bool
timeout time.Duration
handler slog.Handler
metrics Metrics
tracer trace.Tracer
}
func defaultConfig() *Config {
return &Config{
handler: log.NoOp(),
metrics: metrics.NoOp(),
tracer: noop.NewTracerProvider().Tracer("selector's no-op tracer"),
}
}
// WithExecutors configures the Selector with the input executor.Executor(s).
//
// This call returns a cfg.NoOp cfg.Option if the input set of executor.Executor is empty, or contains
// only nil and / or no-op executor.Executor.
func WithExecutors(executors ...executor.Executor) cfg.Option[*Config] {
execs := make([]executor.Executor, 0, len(executors))
for i := range executors {
if executors[i] == nil || executors[i] == executor.NoOp() {
continue
}
execs = append(execs, executors[i])
}
if len(execs) == 0 {
return cfg.NoOp[*Config]{}
}
return cfg.Register(func(config *Config) *Config {
if len(config.exec) == 0 {
config.exec = execs
return config
}
config.exec = append(config.exec, execs...)
return config
})
}
// WithBlock configures the Selector to block (wait) for the underlying executor.Executor to complete the task.
//
// By default, the returned Selector from New is a non-blocking Selector. It mostly relies on the setup of the
// components to at least register the error as metrics or logs, but Exec calls return nil errors if the local context
// times out.
//
// WithBlock waits until the execution is done, so an accurate error value is returned from the Selector.
func WithBlock() cfg.Option[*Config] {
return cfg.Register(func(config *Config) *Config {
config.block = true
return config
})
}
// WithTimeout configures a (non-blocking) Selector to wait a certain duration before detaching of the executable task,
// before continuing to select the next one.
//
// By default, the local context timeout is set to one second. Any negative or zero duration values result in a cfg.NoOp
// cfg.Option being returned.
func WithTimeout(dur time.Duration) cfg.Option[*Config] {
if dur <= 0 {
return cfg.NoOp[*Config]{}
}
return cfg.Register(func(config *Config) *Config {
config.timeout = dur
return config
})
}
// WithMetrics decorates the Selector with the input metrics registry.
func WithMetrics(m Metrics) cfg.Option[*Config] {
if m == nil {
return cfg.NoOp[*Config]{}
}
return cfg.Register(func(config *Config) *Config {
config.metrics = m
return config
})
}
// WithLogger decorates the Selector with the input logger.
func WithLogger(logger *slog.Logger) cfg.Option[*Config] {
if logger == nil {
return cfg.NoOp[*Config]{}
}
return cfg.Register(func(config *Config) *Config {
config.handler = logger.Handler()
return config
})
}
// WithLogHandler decorates the Selector with logging using the input log handler.
func WithLogHandler(handler slog.Handler) cfg.Option[*Config] {
if handler == nil {
return cfg.NoOp[*Config]{}
}
return cfg.Register(func(config *Config) *Config {
config.handler = handler
return config
})
}
// WithTrace decorates the Selector with the input trace.Tracer.
func WithTrace(tracer trace.Tracer) cfg.Option[*Config] {
if tracer == nil {
return cfg.NoOp[*Config]{}
}
return cfg.Register(func(config *Config) *Config {
config.tracer = tracer
return config
})
}