65 lines
1.2 KiB
Go
65 lines
1.2 KiB
Go
package core
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog"
|
|
)
|
|
|
|
type BaseAction interface{}
|
|
|
|
type Action[Q, R any] interface {
|
|
BaseAction
|
|
|
|
Do(context.Context, Q) (R, error)
|
|
}
|
|
|
|
type ActionDecorator[Q, R any, A Action[Q, R]] interface {
|
|
Action[Q, R]
|
|
}
|
|
|
|
type baseAction struct {
|
|
env *Env
|
|
}
|
|
|
|
func newBaseAction(env *Env) baseAction {
|
|
return baseAction{
|
|
env: env,
|
|
}
|
|
}
|
|
|
|
func applyDecorators[Q, R any, A Action[Q, R]](action A) ActionDecorator[Q, R, A] {
|
|
return logActionDecorator[Q, R, A]{
|
|
action: action,
|
|
}
|
|
}
|
|
|
|
type logActionDecorator[Q, R any, A Action[Q, R]] struct {
|
|
action Action[Q, R]
|
|
}
|
|
|
|
func (d logActionDecorator[Q, R, A]) Do(ctx context.Context, params Q) (result R, err error) {
|
|
actionName := getTypeName[A]()
|
|
start := time.Now()
|
|
log := zerolog.Ctx(ctx).With().Str("action_name", actionName).Logger()
|
|
ctx = log.WithContext(ctx)
|
|
|
|
result, err = d.action.Do(ctx, params)
|
|
elapsed := time.Since(start)
|
|
if err != nil {
|
|
log.Warn().Err(err).Dur("elapsed", elapsed).Msg("action failed")
|
|
}
|
|
|
|
log.Info().Dur("elapsed", elapsed).Msg("action successed")
|
|
|
|
return result, err
|
|
}
|
|
|
|
func getTypeName[T any]() string {
|
|
var t T
|
|
out := fmt.Sprintf("%T", t)
|
|
return out
|
|
}
|