Add Functional Options

Signed-off-by: Sherif Abdel-Naby <sherifabdlnaby@gmail.com>
This commit is contained in:
Sherif Abdel-Naby 2021-04-10 07:23:56 +02:00
parent 34c8e9b470
commit b794198e3a
5 changed files with 111 additions and 17 deletions

View file

@ -4,11 +4,11 @@ type ErrorJobPanic struct {
Message string
}
func (e *ErrorJobPanic) Error() string {
func (e ErrorJobPanic) Error() string {
return e.Message
}
func (e *ErrorJobPanic) Unwrap() error {
func (e ErrorJobPanic) Unwrap() error {
return e
}
@ -16,10 +16,10 @@ type ErrorJobStarted struct {
Message string
}
func (e *ErrorJobStarted) Error() string {
func (e ErrorJobStarted) Error() string {
return e.Message
}
func (e *ErrorJobStarted) Unwrap() error {
func (e ErrorJobStarted) Unwrap() error {
return e
}

4
log.go
View file

@ -31,7 +31,7 @@ func (l logger) Named(name string) Logger {
}
func DefaultLogger() Logger {
// TODO suppress debug level
// TODO control verbosity
loggerBase, _ := zap.NewDevelopment()
sugarLogger := loggerBase.Sugar().Named("sched")
return &logger{
@ -41,7 +41,7 @@ func DefaultLogger() Logger {
func NopLogger() Logger {
loggerBase := zap.NewNop()
sugarLogger := loggerBase.Sugar().Named("sched")
sugarLogger := loggerBase.Sugar()
return &logger{
sugarLogger,
}

View file

@ -7,8 +7,6 @@ import (
)
type metrics struct {
// metricsReporter
metricsScope tally.Scope
scheduleUp tally.Gauge
scheduleRunCount tally.Counter
scheduleRunActualElapsed tally.Timer
@ -19,7 +17,6 @@ type metrics struct {
func newMetrics(name string, metricsScope tally.Scope) *metrics {
subScope := metricsScope.SubScope("sched")
return &metrics{
metricsScope: subScope,
scheduleUp: subScope.Tagged(map[string]string{"ID": name}).Gauge("up"),
scheduleRunCount: subScope.Tagged(map[string]string{"ID": name}).Counter("runs"),
scheduleRunActualElapsed: subScope.Tagged(map[string]string{"ID": name}).Timer("run_actual_elapsed_time"),

72
options.go Normal file
View file

@ -0,0 +1,72 @@
package main
import (
"context"
"github.com/uber-go/tally"
"time"
)
type options struct {
logger Logger
metricsScope tally.Scope
context context.Context
// ------------------
initDefaultScope bool
defaultScopePrintEvery time.Duration
}
func defaultOptions() *options {
logger := DefaultLogger()
// TODO cancel loop correctly
ctx := context.Background()
nopMetrics, _ := tally.NewRootScope(tally.ScopeOptions{
Reporter: newConsoleStatsReporter(NopLogger()),
}, 0)
return &options{
logger: logger,
metricsScope: nopMetrics,
context: ctx,
}
}
type Option interface {
apply(*options)
}
type loggerOption struct {
Logger Logger
}
func (l loggerOption) apply(opts *options) {
opts.logger = l.Logger
}
func WithLogger(logger Logger) Option {
return loggerOption{Logger: logger}
}
type metricsOption struct {
metricsScope tally.Scope
// Indicate the usage of default console metrics scope. Metrics scope will be initialized later as it requires the
// Logger() that is going to be used in this schedule.
initConsoleMetrics bool
defaultScopePrintEvery time.Duration
}
func (m metricsOption) apply(opts *options) {
opts.metricsScope = m.metricsScope
opts.initDefaultScope = m.initConsoleMetrics
opts.defaultScopePrintEvery = m.defaultScopePrintEvery
}
func WithMetrics(metricsScope tally.Scope) Option {
return metricsOption{metricsScope: metricsScope, initConsoleMetrics: false, defaultScopePrintEvery: 0}
}
func WithConsoleMetrics(printEvery time.Duration) Option {
return metricsOption{metricsScope: nil, initConsoleMetrics: true, defaultScopePrintEvery: printEvery}
}

View file

@ -43,23 +43,48 @@ type Schedule struct {
}
// NewScheduleWithID NewSchedule
func NewScheduleWithID(ID string, jobFunc func(), timer Timer, logger Logger, metricsScope tally.Scope) *Schedule {
ctx, cancel := context.WithCancel(context.Background())
func NewScheduleWithID(ID string, jobFunc func(), timer Timer, opts ...Option) *Schedule {
var options = defaultOptions()
// Apply Options
for _, option := range opts {
option.apply(options)
}
// Set ID
id := ID
// Set Logger
logger := options.logger.With("ID", id)
// Set Metrics
if options.initDefaultScope {
// TODO closer
//TODO refactor into meth
options.metricsScope, _ = tally.NewRootScope(tally.ScopeOptions{
Reporter: newConsoleStatsReporter(logger.Named("metrics")),
}, options.defaultScopePrintEvery)
}
metrics := *newMetrics(ID, options.metricsScope)
context, cancel := context.WithCancel(options.context)
return &Schedule{
ID: ID,
ID: id,
state: NEW,
jobSrcFunc: jobFunc,
timer: timer,
context: ctx,
context: context,
cancel: cancel,
activeJobs: *newJobMap(),
logger: logger.With("Schedule", ID),
metrics: *newMetrics(ID, metricsScope),
logger: logger,
metrics: metrics,
}
}
func NewSchedule(jobFunc func(), timer Timer, logger Logger, metricsScope tally.Scope) *Schedule {
return NewScheduleWithID(uuid.New().String(), jobFunc, timer, logger, metricsScope)
func NewSchedule(jobFunc func(), timer Timer, opts ...Option) *Schedule {
return NewScheduleWithID(uuid.New().String(), jobFunc, timer, opts...)
}
func (s *Schedule) Start() {