Skip to content

Commit

Permalink
Merge #46
Browse files Browse the repository at this point in the history
46: internal.go: make Service interface optional to implement r=48d90782 a=48d90782



Co-authored-by: Valery Piashchynski <piashchynski_valery@hotmail.com>
  • Loading branch information
bors[bot] and rustatian authored Oct 12, 2020
2 parents 28e3a46 + 121ed70 commit cc9f653
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 46 deletions.
7 changes: 6 additions & 1 deletion calculate_deps.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ func (e *Endure) addEdges() error {
// and we can safely skip the OK parameter here
init, _ := reflect.TypeOf(vrtx.Iface).MethodByName(InitMethodName)

if init.Type == nil {
e.logger.Fatal("init method is absent in struct", zap.String("vertexId", vertexID))
return errNoInitMethodInStructure
}

/* Add the dependencies (if) which this vertex needs to init
Information we know at this step is:
1. vertexID
Expand Down Expand Up @@ -168,7 +173,7 @@ func (e *Endure) addDependersDeps(vertexID string, vertex interface{}) error {
}

func (e *Endure) addInitDeps(vertexID string, initMethod reflect.Method) error {
// S2 init args
// Init function in arguments
initArgs := functionParameters(initMethod)

// iterate over all function parameters
Expand Down
5 changes: 0 additions & 5 deletions endure.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,6 @@ func (e *Endure) Register(vertex interface{}) error {
return errors.New("you should pass pointer to the structure instead of value")
}

ok := t.Implements(reflect.TypeOf((*Service)(nil)).Elem())
if !ok {
return errTypeNotImplementError
}

/* Depender the type
Information we know at this step is:
1. vertexID
Expand Down
1 change: 1 addition & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ var ErrorDuringServe = Error{
var errTypeNotImplementError = errors.New("type should implement Service interface")
var errVertexAlreadyExists = func(name string) error { return fmt.Errorf("vertex `%s` already exists", name) }
var errUnknownErrorOccurred = errors.New("unknown error occurred during the function call")
var errNoInitMethodInStructure = errors.New("init method is absent in struct")
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ require (
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.6.1
go.uber.org/zap v1.16.0
)
)
78 changes: 41 additions & 37 deletions internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,31 @@ func (e *Endure) callConfigureFn(vertex *structures.Vertex, in []reflect.Value)
return nil
}

func (e *Endure) stop(vID string) error {
vertex := e.graph.GetVertex(vID)
if reflect.TypeOf(vertex.Iface).Implements(reflect.TypeOf((*Service)(nil)).Elem()) {
in := make([]reflect.Value, 0, 1)
// add service itself
in = append(in, reflect.ValueOf(vertex.Iface))

err := e.callStopFn(vertex, in)
if err != nil {
e.logger.Error("error occurred during the callStopFn", zap.String("vertex id", vertex.ID))
return err
}

if reflect.TypeOf(vertex.Iface).Implements(reflect.TypeOf((*Graceful)(nil)).Elem()) {
err = e.callCloseFn(vertex.ID, in)
if err != nil {
e.logger.Error("error occurred during the callCloseFn", zap.String("vertex id", vertex.ID))
return err
}
}
}

return nil
}

func (e *Endure) callStopFn(vertex *structures.Vertex, in []reflect.Value) error {
// Call Stop() method, which returns only error (or nil)
e.logger.Debug("stopping vertex", zap.String("vertexId", vertex.ID))
Expand All @@ -441,30 +466,6 @@ func (e *Endure) callStopFn(vertex *structures.Vertex, in []reflect.Value) error
return nil
}

func (e *Endure) stop(vID string) error {
vertex := e.graph.GetVertex(vID)

in := make([]reflect.Value, 0, 1)
// add service itself
in = append(in, reflect.ValueOf(vertex.Iface))

err := e.callStopFn(vertex, in)
if err != nil {
e.logger.Error("error occurred during the callStopFn", zap.String("vertex id", vertex.ID))
return err
}

if reflect.TypeOf(vertex.Iface).Implements(reflect.TypeOf((*Graceful)(nil)).Elem()) {
err = e.callCloseFn(vertex.ID, in)
if err != nil {
e.logger.Error("error occurred during the callCloseFn", zap.String("vertex id", vertex.ID))
return err
}
}

return nil
}

// TODO add stack to the all of the log events
func (e *Endure) callCloseFn(vID string, in []reflect.Value) error {
v := e.graph.GetVertex(vID)
Expand Down Expand Up @@ -563,21 +564,24 @@ func (e *Endure) forceExitHandler(ctx context.Context, data chan *structures.Dll

// serve run configure (if exist) and callServeFn for each node and put the results in the map
func (e *Endure) serve(n *structures.DllNode) error {
// handle all configure
in := make([]reflect.Value, 0, 1)
// add service itself
in = append(in, reflect.ValueOf(n.Vertex.Iface))
// check if type implements serve, if implements, call serve
if reflect.TypeOf(n.Vertex.Iface).Implements(reflect.TypeOf((*Service)(nil)).Elem()) {
// handle all configure
in := make([]reflect.Value, 0, 1)
// add service itself
in = append(in, reflect.ValueOf(n.Vertex.Iface))

res := e.callServeFn(n.Vertex, in)
if res != nil {
e.results.Store(res.vertexID, res)
} else {
e.logger.Error("nil result returned from the vertex", zap.String("vertex id", n.Vertex.ID), zap.String("tip:", "serve function should return initialized channel with errors"))
return fmt.Errorf("nil result returned from the vertex, vertex id: %s", n.Vertex.ID)
}
res := e.callServeFn(n.Vertex, in)
if res != nil {
e.results.Store(res.vertexID, res)
} else {
e.logger.Error("nil result returned from the vertex", zap.String("vertex id", n.Vertex.ID), zap.String("tip:", "serve function should return initialized channel with errors"))
return fmt.Errorf("nil result returned from the vertex, vertex id: %s", n.Vertex.ID)
}

// start poll the vertex
e.poll(res)
// start poll the vertex
e.poll(res)
}

return nil
}
Expand Down
4 changes: 2 additions & 2 deletions tests/backoff/backoff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ func TestEndure_MainThread_Backoff(t *testing.T) {
wg.Wait()

after := time.Now().Second()
// after - now should not be more than 11 as we set in NewContainer
assert.Greater(t, 11, after-now, "time")
// after - now should not be more than 15 as we set in NewContainer
assert.Greater(t, 15, after-now, "time")
}

func TestEndure_BackoffTimers(t *testing.T) {
Expand Down
17 changes: 17 additions & 0 deletions tests/interfaces/interfaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/spiral/endure/tests/interfaces/plugins/plugin3"
"github.com/spiral/endure/tests/interfaces/plugins/plugin4"
"github.com/spiral/endure/tests/interfaces/plugins/plugin5"
notImplPlugin1 "github.com/spiral/endure/tests/interfaces/service/not_implemented_service/plugin1"
notImplPlugin2 "github.com/spiral/endure/tests/interfaces/service/not_implemented_service/plugin2"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -110,3 +112,18 @@ func TestEndure_NamedProvides_WrongType_Fail(t *testing.T) {

assert.NoError(t, c.Stop())
}

func TestEndure_ServiceInterface_NotImplemented_Ok(t *testing.T) {
c, err := endure.NewContainer(endure.DebugLevel)
assert.NoError(t, err)

assert.NoError(t, c.Register(&notImplPlugin1.Foo{}))
assert.NoError(t, c.Register(&notImplPlugin2.Foo{}))

assert.NoError(t, c.Init())

_, err = c.Serve()
assert.NoError(t, err)

assert.NoError(t, c.Stop())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package plugin1

type Foo struct {
}

func (f *Foo) Init() error {
return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package plugin2

type Foo struct {
}

func (f *Foo) Init() error {
return nil
}

0 comments on commit cc9f653

Please sign in to comment.