diff --git a/run/main.go b/example/main.go similarity index 83% rename from run/main.go rename to example/main.go index d4f7767..68d2299 100644 --- a/run/main.go +++ b/example/main.go @@ -1,8 +1,8 @@ package main import ( + "git.echinacities.com/mogfee/protoc-gen-kit/example/service" user "git.echinacities.com/mogfee/protoc-gen-kit/proto/v1" - "git.echinacities.com/mogfee/protoc-gen-kit/service" "github.com/gin-gonic/gin" ) diff --git a/service/service.go b/example/service/service.go similarity index 100% rename from service/service.go rename to example/service/service.go diff --git a/xserver/xserver.go b/xserver/xserver.go new file mode 100644 index 0000000..3feb03c --- /dev/null +++ b/xserver/xserver.go @@ -0,0 +1,73 @@ +package xserver + +import ( + "context" + "os" + "os/signal" + "sync" + "time" +) + +type Server interface { + Start() error + Shutdown(ctx context.Context) error + Name() string +} + +type baseServer struct { + services []Server + wg sync.WaitGroup + errChan chan error + closeChan chan struct{} +} + +func NewServer() *baseServer { + return &baseServer{ + services: make([]Server, 0), + wg: sync.WaitGroup{}, + errChan: make(chan error), + closeChan: make(chan struct{}), + } +} + +func (s *baseServer) Register(srv ...Server) { + s.services = append(s.services, srv...) +} +func (s *baseServer) Start() error { + var hasErr error + for _, v := range s.services { + if hasErr != nil { + break + } + go func(v Server) { + if err := v.Start(); err != nil { + s.errChan <- err + hasErr = err + } + }(v) + } + return hasErr +} + +func (s *baseServer) Shutdown(ctx context.Context) error { + for _, v := range s.services { + go func(v Server) { + <-s.closeChan + if err := v.Shutdown(context.Background()); err != nil { + s.errChan <- err + } + }(v) + } + return <-s.errChan +} +func (s *baseServer) NotifyClose() { + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, os.Interrupt) + <-signalChan + close(s.closeChan) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + s.Shutdown(ctx) + time.Sleep(time.Second) +}