diff --git a/dep/out.go b/dep/out.go index 6bdbab9..bf2739b 100644 --- a/dep/out.go +++ b/dep/out.go @@ -13,7 +13,7 @@ type Out struct { Method string } -func OutType(tp any, method any) *Out { +func Bind(tp any, method any) *Out { if reflect.TypeOf(tp) == nil { panic("nil type provided, should be of the form of: (*FooBar)(nil), not (FooBar)(nil)") } @@ -38,6 +38,10 @@ func OutType(tp any, method any) *Out { } } + if r.NumIn() > 0 { + panic("dep.Bind function should not receive any arguments") + } + return &Out{ Type: reflect.TypeOf(tp).Elem(), Method: getFunctionName(method), diff --git a/dep/out_test.go b/dep/out_test.go index ca9bb25..1869a1f 100644 --- a/dep/out_test.go +++ b/dep/out_test.go @@ -25,7 +25,7 @@ func (p *Plugin) F() (*TestStruct, error) { func TestOutType(t *testing.T) { p := Plugin{} - tt := OutType((*FooBar)(nil), p.F) + tt := Bind((*FooBar)(nil), p.F) assert.Equal(t, reflect.Interface, tt.Type.Kind()) assert.Equal(t, "F", tt.Method) diff --git a/examples/sample_1/modules/logger/logger.go b/examples/sample_1/modules/logger/logger.go index 18f10da..1745818 100755 --- a/examples/sample_1/modules/logger/logger.go +++ b/examples/sample_1/modules/logger/logger.go @@ -29,7 +29,7 @@ func (l *Logger) Init() error { func (l *Logger) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*SuperLogger)(nil), l.LoggerInstance), + dep.Bind((*SuperLogger)(nil), l.LoggerInstance), } } diff --git a/init.go b/init.go index fab3658..e120477 100644 --- a/init.go +++ b/init.go @@ -29,10 +29,10 @@ func (e *Endure) init() error { inVals = append(inVals, reflect.ValueOf(vertices[i].Plugin())) // has deps if > 1 if len(args) > 1 { - for j := 0; j < len(args[1:]); j++ { - arg := args[1:][j] - - plugin := e.registar.Implements(arg) + // exclude first arg (it's receiver) + arg := args[1:] + for j := 0; j < len(arg); j++ { + plugin := e.registar.ImplementsExcept(arg[j], vertices[i].Plugin()) if len(plugin) == 0 { del := e.graph.Remove(vertices[i].Plugin()) for k := 0; k < len(del); k++ { @@ -53,7 +53,7 @@ func (e *Endure) init() error { // we have a method, thus we need to get the value, because previous plugin have registered it's provided deps case false: - value, ok := e.registar.TypeValue(plugin[0].Plugin(), arg) + value, ok := e.registar.TypeValue(plugin[0].Plugin(), arg[j]) if !ok { return errors.E("this is likely a bug, nil value from the implements. Value should be initialized due to the topological order") } diff --git a/registar/registar.go b/registar/registar.go index ed6fdce..81531d9 100644 --- a/registar/registar.go +++ b/registar/registar.go @@ -91,47 +91,7 @@ func (r *Registar) Remove(plugin any) { delete(r.types, reflect.TypeOf(plugin)) } -// Implements check that there are plugins (with Provides) that implement all types -func (r *Registar) Implements(tp reflect.Type) []*implements { - var impl []*implements - // range over all registered types (basically all that we know about plugins and providers) - for k, entry := range r.types { - // iterate over types, provided by the user - // plugin (w or w/o provides) should implement this type - - // our plugin might implement one of the needed types - // if not, check if the plugin provides some types which might implement the type - if k.Implements(tp) { - impl = append(impl, &implements{ - plugin: entry.Plugin(), - weight: entry.Weight(), - }) - continue - } - - // here we check that provides - for j := 0; j < len(entry.returnedTypes); j++ { - provided := entry.returnedTypes[j] - if provided.retType.Implements(tp) { - impl = append(impl, - &implements{ - plugin: entry.Plugin(), - weight: entry.Weight(), - methods: provided.method, - }, - ) - } - } - } - - // sort by weight - sort.Slice(impl, func(i, j int) bool { - return impl[i].weight > impl[j].weight - }) - - return impl -} - +// ImplementsExcept check for the deps which implements the type 'tp' except the plugin itself (or any other plugin) func (r *Registar) ImplementsExcept(tp reflect.Type, plugin any) []*implements { var impl []*implements excl := reflect.TypeOf(plugin) diff --git a/resolveEdges.go b/resolveEdges.go index d509742..536f297 100755 --- a/resolveEdges.go +++ b/resolveEdges.go @@ -72,7 +72,7 @@ func (e *Endure) resolveEdges() error { count := 0 if len(args) > 1 { for j := 1; j < len(args); j++ { - res := e.registar.Implements(args[j]) + res := e.registar.ImplementsExcept(args[j], vertices[i].Plugin()) count += len(res) if len(res) > 0 { for k := 0; k < len(res); k++ { diff --git a/tests/general/test1/p1/plugin.go b/tests/general/test1/p1/plugin.go index 7be0ec1..9714994 100644 --- a/tests/general/test1/p1/plugin.go +++ b/tests/general/test1/p1/plugin.go @@ -37,7 +37,7 @@ func (p *Plugin) Weight() uint { func (p *Plugin) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*Fooer)(nil), p.InitFoo), + dep.Bind((*Fooer)(nil), p.InitFoo), } } diff --git a/tests/general/test1/p5/plugin.go b/tests/general/test1/p5/plugin.go index 3290e59..125602a 100644 --- a/tests/general/test1/p5/plugin.go +++ b/tests/general/test1/p5/plugin.go @@ -36,7 +36,7 @@ func (p *Plugin) Name() string { func (p *Plugin) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*Fooer)(nil), p.InitFoo), + dep.Bind((*Fooer)(nil), p.InitFoo), } } diff --git a/tests/general/test2/p1/plugin.go b/tests/general/test2/p1/plugin.go index 7be0ec1..9714994 100644 --- a/tests/general/test2/p1/plugin.go +++ b/tests/general/test2/p1/plugin.go @@ -37,7 +37,7 @@ func (p *Plugin) Weight() uint { func (p *Plugin) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*Fooer)(nil), p.InitFoo), + dep.Bind((*Fooer)(nil), p.InitFoo), } } diff --git a/tests/general/test2/p5/plugin.go b/tests/general/test2/p5/plugin.go index bfa269f..9cd2309 100644 --- a/tests/general/test2/p5/plugin.go +++ b/tests/general/test2/p5/plugin.go @@ -39,7 +39,7 @@ func (p *Plugin) Weight() uint { func (p *Plugin) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*Fooer)(nil), p.InitFoo), + dep.Bind((*Fooer)(nil), p.InitFoo), } } diff --git a/tests/general/test3/p1/pkg/impl.go b/tests/general/test3/p1/pkg/impl.go new file mode 100644 index 0000000..f3f7275 --- /dev/null +++ b/tests/general/test3/p1/pkg/impl.go @@ -0,0 +1,22 @@ +package pkg + +type Foo struct { + N string +} + +func InitFoo() *Foo { + return &Foo{} +} + +func (f *Foo) Init(val string) error { + f.N = val + return nil +} + +func (f *Foo) FooBar() string { + return f.N +} + +func (f *Foo) Name() string { + return "Foo" +} diff --git a/tests/general/test3/p1/plugin.go b/tests/general/test3/p1/plugin.go new file mode 100644 index 0000000..59fea35 --- /dev/null +++ b/tests/general/test3/p1/plugin.go @@ -0,0 +1,54 @@ +package p1 + +import ( + "context" + + "github.com/roadrunner-server/endure/v2/dep" + "github.com/roadrunner-server/endure/v2/tests/general/test3/p1/pkg" +) + +type Plugin struct{} + +type Fooer interface { + FooBar() string + Init(val string) error +} + +type Named interface { + Name() string +} + +func (p *Plugin) Init() error { + println("initp1") + return nil +} + +func (p *Plugin) Serve() chan error { + return make(chan error, 1) +} + +func (p *Plugin) Stop(context.Context) error { + return nil +} + +func (p *Plugin) Name() string { + return "p1" +} + +func (p *Plugin) Weight() uint { + return 10 +} + +func (p *Plugin) Foo() string { + return "foo" +} + +func (p *Plugin) Provides() []*dep.Out { + return []*dep.Out{ + dep.Bind((*Fooer)(nil), p.InitFoo), + } +} + +func (p *Plugin) InitFoo() *pkg.Foo { + return pkg.InitFoo() +} diff --git a/tests/general/test3/p2/plugin.go b/tests/general/test3/p2/plugin.go new file mode 100644 index 0000000..156e38b --- /dev/null +++ b/tests/general/test3/p2/plugin.go @@ -0,0 +1,43 @@ +package p2 + +import ( + "context" + + "github.com/roadrunner-server/endure/v2/dep" +) + +type Plugin struct { +} + +type Fooer interface { + FooBar() string + Init(val string) error +} + +func (p *Plugin) Init() error { + return nil +} + +func (p *Plugin) Serve() chan error { + return make(chan error, 1) +} + +func (p *Plugin) Stop(context.Context) error { + return nil +} + +func (p *Plugin) Name() string { + return "p2" +} + +func callback(p any) { + pp := p.(Fooer) + _ = pp.Init("foo") + println(pp.FooBar()) +} + +func (p *Plugin) Collects() []*dep.In { + return []*dep.In{ + dep.Fits(callback, (*Fooer)(nil)), + } +} diff --git a/tests/general/test3/test3_test.go b/tests/general/test3/test3_test.go new file mode 100644 index 0000000..7e38e47 --- /dev/null +++ b/tests/general/test3/test3_test.go @@ -0,0 +1,31 @@ +package test3 + +import ( + "testing" + + "github.com/roadrunner-server/endure/v2" + "github.com/roadrunner-server/endure/v2/tests/general/test3/p1" + "github.com/roadrunner-server/endure/v2/tests/general/test3/p2" + "github.com/stretchr/testify/assert" + "golang.org/x/exp/slog" +) + +func Test1(t *testing.T) { + end := endure.New(slog.LevelDebug) + + err := end.Register(&p1.Plugin{}) + assert.NoError(t, err) + + err = end.Register(&p2.Plugin{}) + assert.NoError(t, err) + + assert.NoError(t, err) + + err = end.Init() + assert.NoError(t, err) + + _, err = end.Serve() + assert.NoError(t, err) + + assert.NoError(t, end.Stop()) +} diff --git a/tests/happy_scenarios/plugin2/plugin2.go b/tests/happy_scenarios/plugin2/plugin2.go index f543312..7f56dc3 100755 --- a/tests/happy_scenarios/plugin2/plugin2.go +++ b/tests/happy_scenarios/plugin2/plugin2.go @@ -28,7 +28,7 @@ func (s2 *S2) Init(P4DB) error { func (s2 *S2) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*P2DB)(nil), s2.CreateDB), + dep.Bind((*P2DB)(nil), s2.CreateDB), } } diff --git a/tests/happy_scenarios/plugin4/plugin4.go b/tests/happy_scenarios/plugin4/plugin4.go index b16f44d..4d4b0d2 100755 --- a/tests/happy_scenarios/plugin4/plugin4.go +++ b/tests/happy_scenarios/plugin4/plugin4.go @@ -31,7 +31,7 @@ func (s *S4) Init(_ IFOO5DB, fooWriter FooWriter) error { func (s *S4) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*P4DB)(nil), s.CreateAnotherDB), + dep.Bind((*P4DB)(nil), s.CreateAnotherDB), } } diff --git a/tests/happy_scenarios/plugin6/plugin6.go b/tests/happy_scenarios/plugin6/plugin6.go index 6022a87..8cab93c 100755 --- a/tests/happy_scenarios/plugin6/plugin6.go +++ b/tests/happy_scenarios/plugin6/plugin6.go @@ -33,7 +33,7 @@ func (s *S6Interface) Stop(context.Context) error { func (s *S6Interface) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*FooWriter)(nil), s.ProvideInterface), + dep.Bind((*FooWriter)(nil), s.ProvideInterface), } } diff --git a/tests/interfaces/named/randominterface/plugin2.go b/tests/interfaces/named/randominterface/plugin2.go index 8bb56ac..a612a38 100755 --- a/tests/interfaces/named/randominterface/plugin2.go +++ b/tests/interfaces/named/randominterface/plugin2.go @@ -29,7 +29,7 @@ func (f *Plugin2) Stop(context.Context) error { // But provide some func (f *Plugin2) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*SuperInterface)(nil), f.ProvideDB), + dep.Bind((*SuperInterface)(nil), f.ProvideDB), } } diff --git a/tests/interfaces/named/registers/plugin2.go b/tests/interfaces/named/registers/plugin2.go index e324f95..d5f67c9 100755 --- a/tests/interfaces/named/registers/plugin2.go +++ b/tests/interfaces/named/registers/plugin2.go @@ -39,7 +39,7 @@ func (f *Plugin2) Stop(context.Context) error { func (f *Plugin2) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*IDB)(nil), f.ProvideDB), + dep.Bind((*IDB)(nil), f.ProvideDB), } } diff --git a/tests/interfaces/plugins/plugin2/plugin2.go b/tests/interfaces/plugins/plugin2/plugin2.go index 4c9bdda..feca8e7 100755 --- a/tests/interfaces/plugins/plugin2/plugin2.go +++ b/tests/interfaces/plugins/plugin2/plugin2.go @@ -33,7 +33,7 @@ func (s *Plugin2) Stop(context.Context) error { func (s *Plugin2) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*FooWriter)(nil), s.ProvideInterface), + dep.Bind((*FooWriter)(nil), s.ProvideInterface), } } diff --git a/tests/interfaces/plugins/plugin6/plugin.go b/tests/interfaces/plugins/plugin6/plugin.go index 58fd24c..4a7fa30 100644 --- a/tests/interfaces/plugins/plugin6/plugin.go +++ b/tests/interfaces/plugins/plugin6/plugin.go @@ -44,9 +44,9 @@ func (p *Plugin) Stop(context.Context) error { // Provides declares factory methods. func (p *Plugin) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*SuperInterface)(nil), p.ProvideWithName), - dep.OutType((*SuperInterface)(nil), p.ProvideWithInterfaceAndStruct), - dep.OutType((*SuperInterface)(nil), p.ProvideWithOutName), + dep.Bind((*SuperInterface)(nil), p.ProvideWithName), + dep.Bind((*SuperInterface)(nil), p.ProvideWithInterfaceAndStruct), + dep.Bind((*SuperInterface)(nil), p.ProvideWithOutName), } } diff --git a/tests/issues/issue54/plugin3/plugin3.go b/tests/issues/issue54/plugin3/plugin3.go index 08bade5..72febd0 100644 --- a/tests/issues/issue54/plugin3/plugin3.go +++ b/tests/issues/issue54/plugin3/plugin3.go @@ -51,8 +51,8 @@ func (p *Plugin3) Stop(context.Context) error { func (p *Plugin3) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*IPlugin3Dep)(nil), p.AddDB), - dep.OutType((*IPlugin3OtherDepM)(nil), p.OtherType), + dep.Bind((*IPlugin3Dep)(nil), p.AddDB), + dep.Bind((*IPlugin3OtherDepM)(nil), p.OtherType), } } diff --git a/tests/issues/issue66/plugin3/plugin3.go b/tests/issues/issue66/plugin3/plugin3.go index 74edb44..5296f33 100644 --- a/tests/issues/issue66/plugin3/plugin3.go +++ b/tests/issues/issue66/plugin3/plugin3.go @@ -39,7 +39,7 @@ func (p *Plugin3) Stop(context.Context) error { func (p *Plugin3) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*IDB3)(nil), p.ProvidePlugin3DB), + dep.Bind((*IDB3)(nil), p.ProvidePlugin3DB), } } diff --git a/tests/stress/ServeErr/foo4ServeError.go b/tests/stress/ServeErr/foo4ServeError.go index 69712d1..20b50cf 100755 --- a/tests/stress/ServeErr/foo4ServeError.go +++ b/tests/stress/ServeErr/foo4ServeError.go @@ -34,7 +34,7 @@ func (s *S4ServeError) Init(S5Deper) error { // But provide some func (s *S4ServeError) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*SuperSelecter)(nil), s.CreateAnotherDB), + dep.Bind((*SuperSelecter)(nil), s.CreateAnotherDB), } } diff --git a/tests/stress/ServeErr/plugin2.go b/tests/stress/ServeErr/plugin2.go index 14c44a5..64d5d09 100755 --- a/tests/stress/ServeErr/plugin2.go +++ b/tests/stress/ServeErr/plugin2.go @@ -22,7 +22,7 @@ func (s2 *S2) Init(SuperSelecter) error { func (s2 *S2) Provides() []*dep.Out { return []*dep.Out{ - dep.OutType((*SuperDB)(nil), s2.CreateDB), + dep.Bind((*SuperDB)(nil), s2.CreateDB), } }