diff --git a/options.go b/options.go index 95636364..37164a71 100644 --- a/options.go +++ b/options.go @@ -211,6 +211,7 @@ func Stores(s ...store.Store) Option { } // Logger set the logger to use +// //nolint:gocyclo func Logger(l logger.Logger, opts ...LoggerOption) Option { return func(o *Options) error { @@ -329,6 +330,7 @@ func Meters(m ...meter.Meter) Option { // Register sets the register for the service // and the underlying components +// //nolint:gocyclo func Register(r register.Register, opts ...RegisterOption) Option { return func(o *Options) error { @@ -403,6 +405,7 @@ func RegisterBroker(n string) RegisterOption { } // Tracer sets the tracer +// //nolint:gocyclo func Tracer(t tracer.Tracer, opts ...TracerOption) Option { return func(o *Options) error { diff --git a/options/hooks.go b/options/hooks.go new file mode 100644 index 00000000..48a45ad2 --- /dev/null +++ b/options/hooks.go @@ -0,0 +1,31 @@ +package options // import "go.unistack.org/micro/v3/options" + +// Hook func interface +type Hook interface{} + +// Hooks func slice +type Hooks []Hook + +// Append is used to add hooks +func (hs *Hooks) Append(h ...Hook) { + *hs = append(*hs, h...) +} + +// Replace is used to set hooks +func (hs *Hooks) Replace(h ...Hook) { + *hs = h +} + +// EachNext is used to itearate over hooks forward +func (hs *Hooks) EachNext(fn func(Hook)) { + for idx := 0; idx < len(*hs); idx++ { + fn((*hs)[idx]) + } +} + +// EachPrev is used to iterate over hooks backward +func (hs *Hooks) EachPrev(fn func(Hook)) { + for idx := len(*hs) - 1; idx >= 0; idx-- { + fn((*hs)[idx]) + } +} diff --git a/options/hooks_test.go b/options/hooks_test.go new file mode 100644 index 00000000..be84d3bd --- /dev/null +++ b/options/hooks_test.go @@ -0,0 +1,65 @@ +package options + +import "testing" + +func TestHooks_Append(t *testing.T) { + fn1 := func() {} + fn2 := func() {} + hs := &Hooks{} + hs.Append(fn1, fn2) + if len(*hs) != 2 { + t.Fatalf("unexpected Append error") + } +} + +func TestHooks_Replace(t *testing.T) { + fn1 := func() {} + fn2 := func() {} + hs := &Hooks{} + hs.Append(fn1, fn2, fn1) + if len(*hs) != 3 { + t.Fatalf("unexpected Append error") + } + hs.Replace(fn1, fn2) + if len(*hs) != 2 { + t.Fatalf("unexpected Replace error") + } +} + +func TestHooks_EachNext(t *testing.T) { + n := 5 + fn1 := func() { + n *= 2 + } + fn2 := func() { + n -= 10 + } + hs := &Hooks{} + hs.Append(fn1, fn2) + + hs.EachNext(func(h Hook) { + h.(func())() + }) + if n != 0 { + t.Fatalf("unexpected EachNext") + } +} + +func TestHooks_EachPrev(t *testing.T) { + n := 5 + fn1 := func() { + n *= 2 + } + fn2 := func() { + n -= 10 + } + hs := &Hooks{} + hs.Append(fn2, fn1) + + hs.EachPrev(func(h Hook) { + h.(func())() + }) + if n != 0 { + t.Fatalf("unexpected EachPrev") + } +} diff --git a/server/options.go b/server/options.go index cf269772..8ab8c0d2 100644 --- a/server/options.go +++ b/server/options.go @@ -13,6 +13,7 @@ import ( "go.unistack.org/micro/v3/metadata" "go.unistack.org/micro/v3/meter" "go.unistack.org/micro/v3/network/transport" + "go.unistack.org/micro/v3/options" "go.unistack.org/micro/v3/register" "go.unistack.org/micro/v3/tracer" "go.unistack.org/micro/v3/util/id" @@ -83,6 +84,8 @@ type Options struct { MaxConn int // DeregisterAttempts holds the number of deregister attempts before error DeregisterAttempts int + // Hooks may contains SubscriberWrapper, HandlerWrapper or Server func wrapper + Hooks options.Hooks } // NewOptions returns new options struct with default or passed values