add service test and shutdown based on context
This commit is contained in:
parent
e84e5ae303
commit
942985ce51
24
options.go
24
options.go
@ -28,6 +28,8 @@ type Options struct {
|
||||
|
||||
// Before and After funcs
|
||||
BeforeStart []func() error
|
||||
BeforeStop []func() error
|
||||
AfterStart []func() error
|
||||
AfterStop []func() error
|
||||
|
||||
// Other options for implementations of the interface
|
||||
@ -43,6 +45,7 @@ func newOptions(opts ...Option) Options {
|
||||
Server: server.DefaultServer,
|
||||
Registry: registry.DefaultRegistry,
|
||||
Transport: transport.DefaultTransport,
|
||||
Context: context.Background(),
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
@ -73,6 +76,15 @@ func Client(c client.Client) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// Context specifies a context for the service
|
||||
// Can be used to signal shutdown of the service
|
||||
// Can be used for extra option values
|
||||
func Context(ctx context.Context) Option {
|
||||
return func(o *Options) {
|
||||
o.Context = ctx
|
||||
}
|
||||
}
|
||||
|
||||
func Server(s server.Server) Option {
|
||||
return func(o *Options) {
|
||||
o.Server = s
|
||||
@ -204,6 +216,18 @@ func BeforeStart(fn func() error) Option {
|
||||
}
|
||||
}
|
||||
|
||||
func BeforeStop(fn func() error) Option {
|
||||
return func(o *Options) {
|
||||
o.BeforeStop = append(o.BeforeStop, fn)
|
||||
}
|
||||
}
|
||||
|
||||
func AfterStart(fn func() error) Option {
|
||||
return func(o *Options) {
|
||||
o.AfterStart = append(o.AfterStart, fn)
|
||||
}
|
||||
}
|
||||
|
||||
func AfterStop(fn func() error) Option {
|
||||
return func(o *Options) {
|
||||
o.AfterStop = append(o.AfterStop, fn)
|
||||
|
27
service.go
27
service.go
@ -120,10 +120,24 @@ func (s *service) Start() error {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, fn := range s.opts.AfterStart {
|
||||
if err := fn(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) Stop() error {
|
||||
var gerr error
|
||||
|
||||
for _, fn := range s.opts.BeforeStop {
|
||||
if err := fn(); err != nil {
|
||||
gerr = err
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.opts.Server.Deregister(); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -132,15 +146,12 @@ func (s *service) Stop() error {
|
||||
return err
|
||||
}
|
||||
|
||||
var gerr error
|
||||
for _, fn := range s.opts.AfterStop {
|
||||
if err := fn(); err != nil {
|
||||
// should we bail if it fails?
|
||||
// other funcs will not be executed
|
||||
// seems wrong
|
||||
gerr = err
|
||||
}
|
||||
}
|
||||
|
||||
return gerr
|
||||
}
|
||||
|
||||
@ -155,7 +166,13 @@ func (s *service) Run() error {
|
||||
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)
|
||||
<-ch
|
||||
|
||||
select {
|
||||
// wait on kill signal
|
||||
case <-ch:
|
||||
// wait on context cancel
|
||||
case <-s.opts.Context.Done():
|
||||
}
|
||||
|
||||
// exit reg loop
|
||||
close(ex)
|
||||
|
65
service_test.go
Normal file
65
service_test.go
Normal file
@ -0,0 +1,65 @@
|
||||
package micro
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/micro/go-micro/registry/mock"
|
||||
proto "github.com/micro/go-micro/server/debug/proto"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
// cancellation context
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
// create service
|
||||
service := NewService(
|
||||
Name("test.service"),
|
||||
Context(ctx),
|
||||
Registry(mock.NewRegistry()),
|
||||
AfterStart(func() error {
|
||||
wg.Done()
|
||||
return nil
|
||||
}),
|
||||
)
|
||||
|
||||
// we can't test service.Init as it parses the command line
|
||||
// service.Init()
|
||||
|
||||
// register handler
|
||||
// do that later
|
||||
|
||||
go func() {
|
||||
// wait for start
|
||||
wg.Wait()
|
||||
|
||||
// test call debug
|
||||
req := service.Client().NewRequest(
|
||||
"test.service",
|
||||
"Debug.Health",
|
||||
new(proto.HealthRequest),
|
||||
)
|
||||
|
||||
rsp := new(proto.HealthResponse)
|
||||
|
||||
err := service.Client().Call(context.TODO(), req, rsp)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if rsp.Status != "ok" {
|
||||
t.Fatalf("service response: %s", rsp.Status)
|
||||
}
|
||||
|
||||
// shutdown the service
|
||||
cancel()
|
||||
}()
|
||||
|
||||
// run service
|
||||
service.Run()
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user