add internal/service base logic

pull/196/head
Michael Li 2 years ago
parent 3bf5dd53d5
commit 6570286a4e
No known key found for this signature in database

@ -6,14 +6,26 @@ import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
gin "github.com/gin-gonic/gin"
)
type LoginReq struct {
AgentInfo AgentInfo `json:"agent_info"`
Name string `json:"name"`
Passwd string `json:"passwd"`
}
type AgentInfo struct {
Platform string `json:"platform"`
UserAgent string `json:"user_agent"`
}
type LoginResp struct {
UserInfo
ServerInfo ServerInfo `json:"server_info"`
JwtToken string `json:"jwt_token"`
}
type ServerInfo struct {
ApiVer string `json:"api_ver"`
}
@ -22,26 +34,14 @@ type UserInfo struct {
Name string `json:"name"`
}
type LoginReq struct {
AgentInfo AgentInfo `json:"agent_info"`
Name string `json:"name"`
Passwd string `json:"passwd"`
}
type LoginResp struct {
UserInfo
ServerInfo ServerInfo `json:"server_info"`
JwtToken string `json:"jwt_token"`
}
type WebCore interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
Index(c *gin.Context) mir.Error
Articles(c *gin.Context) mir.Error
Login(c *gin.Context, req *LoginReq) (*LoginResp, mir.Error)
Logout(c *gin.Context) mir.Error
Login(c *gin.Context, req *LoginReq) (*LoginResp, mir.Error)
Articles(c *gin.Context) mir.Error
Index(c *gin.Context) mir.Error
mustEmbedUnimplementedWebCoreServant()
}
@ -53,10 +53,10 @@ type WebCoreBinding interface {
}
type WebCoreRender interface {
RenderIndex(c *gin.Context, err mir.Error)
RenderArticles(c *gin.Context, err mir.Error)
RenderLogin(c *gin.Context, data *LoginResp, err mir.Error)
RenderLogout(c *gin.Context, err mir.Error)
RenderLogin(c *gin.Context, data *LoginResp, err mir.Error)
RenderArticles(c *gin.Context, err mir.Error)
RenderIndex(c *gin.Context, err mir.Error)
mustEmbedUnimplementedWebCoreRender()
}
@ -69,12 +69,10 @@ func RegisterWebCoreServant(e *gin.Engine, s WebCore, b WebCoreBinding, r WebCor
router.Use(middlewares...)
// register routes info to router
router.Handle("GET", "/index/", func(c *gin.Context) {
r.RenderIndex(c, s.Index(c))
})
router.Handle("GET", "/articles/:category/", func(c *gin.Context) {
r.RenderArticles(c, s.Articles(c))
router.Handle("POST", "/user/logout/", func(c *gin.Context) {
r.RenderLogout(c, s.Logout(c))
})
router.Handle("POST", "/user/login/", func(c *gin.Context) {
req, err := b.BindLogin(c)
if err != nil {
@ -83,33 +81,30 @@ func RegisterWebCoreServant(e *gin.Engine, s WebCore, b WebCoreBinding, r WebCor
resp, err := s.Login(c, req)
r.RenderLogin(c, resp, err)
})
router.Handle("POST", "/user/logout/", func(c *gin.Context) {
r.RenderLogout(c, s.Logout(c))
})
}
// UnimplementedWebCoreServant can be embedded to have forward compatible implementations.
type UnimplementedWebCoreServant struct{}
{
h := func(c *gin.Context) {
r.RenderArticles(c, s.Articles(c))
}
router.Handle("HEAD", "/articles/:category/", h)
router.Handle("GET", "/articles/:category/", h)
}
router.Handle("GET", "/index/", func(c *gin.Context) {
r.RenderIndex(c, s.Index(c))
})
// UnimplementedWebCoreBinding can be embedded to have forward compatible implementations.
type UnimplementedWebCoreBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
// UnimplementedWebCoreRender can be embedded to have forward compatible implementations.
type UnimplementedWebCoreRender struct {
RenderAny func(*gin.Context, any, mir.Error)
// UnimplementedWebCoreServant can be embedded to have forward compatible implementations.
type UnimplementedWebCoreServant struct {
}
func (UnimplementedWebCoreServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedWebCoreServant) Index(c *gin.Context) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedWebCoreServant) Articles(c *gin.Context) mir.Error {
func (UnimplementedWebCoreServant) Logout(c *gin.Context) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
@ -117,25 +112,22 @@ func (UnimplementedWebCoreServant) Login(c *gin.Context, req *LoginReq) (*LoginR
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedWebCoreServant) Logout(c *gin.Context) mir.Error {
func (UnimplementedWebCoreServant) Articles(c *gin.Context) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedWebCoreServant) mustEmbedUnimplementedWebCoreServant() {}
func (b *UnimplementedWebCoreBinding) BindLogin(c *gin.Context) (*LoginReq, mir.Error) {
obj := new(LoginReq)
err := b.BindAny(c, obj)
return obj, err
func (UnimplementedWebCoreServant) Index(c *gin.Context) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (b *UnimplementedWebCoreBinding) mustEmbedUnimplementedWebCoreBinding() {}
func (UnimplementedWebCoreServant) mustEmbedUnimplementedWebCoreServant() {}
func (r *UnimplementedWebCoreRender) RenderIndex(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
// UnimplementedWebCoreRender can be embedded to have forward compatible implementations.
type UnimplementedWebCoreRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedWebCoreRender) RenderArticles(c *gin.Context, err mir.Error) {
func (r *UnimplementedWebCoreRender) RenderLogout(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
@ -143,8 +135,25 @@ func (r *UnimplementedWebCoreRender) RenderLogin(c *gin.Context, data *LoginResp
r.RenderAny(c, data, err)
}
func (r *UnimplementedWebCoreRender) RenderLogout(c *gin.Context, err mir.Error) {
func (r *UnimplementedWebCoreRender) RenderArticles(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedWebCoreRender) RenderIndex(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedWebCoreRender) mustEmbedUnimplementedWebCoreRender() {}
// UnimplementedWebCoreBinding can be embedded to have forward compatible implementations.
type UnimplementedWebCoreBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedWebCoreBinding) BindLogin(c *gin.Context) (*LoginReq, mir.Error) {
obj := new(LoginReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedWebCoreBinding) mustEmbedUnimplementedWebCoreBinding() {}

@ -17,7 +17,7 @@ import (
func main() {
log.Println("generate code start")
opts := Options{
RunMode(InSerialMode),
RunMode(InSerialDebugMode),
GeneratorName(GeneratorGin),
SinkPath("auto"),
}

@ -38,7 +38,7 @@ type WebCore struct {
Chain Chain `mir:"-"`
Group Group `mir:"v1"`
Index func(Get) `mir:"/index/"`
Articles func(Get) `mir:"/articles/:category/"`
Articles func(Get, Head) `mir:"/articles/:category/"`
Login func(Post, LoginReq) LoginResp `mir:"/user/login/"`
Logout func(Post) `mir:"/user/logout/"`
}

@ -15,16 +15,12 @@ import (
// RegisterWebServants register all the servants to gin.Engine
func RegisterWebServants(e *gin.Engine) {
// 按需注册 docs、静态资源
{
docs.RegisterDocs(e)
statick.RegisterStatick(e)
}
docs.RegisterDocs(e)
statick.RegisterStatick(e)
cfg.Be("LocalOSS", func() {
localoss.RouteLocalOSS(e)
})
web.RouteWeb(e)
{
cfg.Be("LocalOSS", func() {
localoss.RouteLocalOSS(e)
})
}
}

@ -0,0 +1,83 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package service
import (
"context"
"net/http"
"sync"
"github.com/gin-gonic/gin"
)
var (
httpServers = make(map[string]*httpServer)
)
const (
httpServerInitilized uint8 = iota + 1
httpServerStarted
httpServerStoped
)
// httpServer wraper for gin.engine and http.Server
type httpServer struct {
sync.RWMutex
e *gin.Engine
server *http.Server
serverStatus uint8
}
func (s *httpServer) status() uint8 {
s.RLock()
defer s.RUnlock()
return s.serverStatus
}
func (s *httpServer) start() error {
s.Lock()
if s.serverStatus == httpServerStarted || s.serverStatus == httpServerStoped {
return nil
}
oldStatus := s.serverStatus
s.serverStatus = httpServerStarted
s.Unlock()
if err := s.server.ListenAndServe(); err != nil {
s.Lock()
s.serverStatus = oldStatus
s.Unlock()
return err
}
return nil
}
func (s *httpServer) stop() error {
s.Lock()
defer s.Unlock()
if s.serverStatus == httpServerStoped || s.serverStatus == httpServerInitilized {
return nil
}
if err := s.server.Shutdown(context.Background()); err != nil {
return err
}
s.serverStatus = httpServerStoped
return nil
}
func httpServerFrom(addr string, newServer func() *httpServer) *httpServer {
s, exist := httpServers[addr]
if exist {
return s
}
s = newServer()
s.serverStatus = httpServerInitilized
httpServers[addr] = s
return s
}

@ -0,0 +1,49 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package service
import (
"github.com/gin-gonic/gin"
)
type httpService interface {
Service
registerRoute(e *gin.Engine)
}
type baseHttpService struct {
baseService
server *httpServer
}
func (s *baseHttpService) Init() error {
if s.server.status() != httpServerStarted {
s.registerRoute(s.server.e)
}
return nil
}
func (s *baseHttpService) Start() error {
if err := s.server.start(); err != nil {
return err
}
return nil
}
func (s *baseHttpService) Stop() error {
return s.server.stop()
}
func (s *baseHttpService) registerRoute(e *gin.Engine) {
// default empty
}
func newBaseHttpService(s *httpServer) httpService {
return &baseHttpService{
server: s,
}
}

@ -4,14 +4,36 @@
package service
import (
"log"
"github.com/rocboss/paopao-ce/pkg/types"
)
type Service interface {
Name() string
Start()
Stop()
Init() error
Start() error
Stop() error
}
type baseService struct{}
type baseService types.Empty
func (baseService) Name() string {
return ""
}
func (baseService) String() string {
return ""
}
func InitService() (ss []Service) {
ss = append(ss, newWebService())
for _, s := range ss {
if err := s.Init(); err != nil {
log.Fatalf("initial %s service error: %s", s.Name(), err)
}
}
return
}

@ -5,9 +5,7 @@
package service
import (
"context"
"fmt"
"log"
"net/http"
"github.com/fatih/color"
@ -18,23 +16,15 @@ import (
)
type webService struct {
baseService
server *http.Server
httpService
}
func (s *webService) Name() string {
return "WebService"
}
func (s *webService) Start() {
if err := s.server.ListenAndServe(); err != nil {
log.Fatalf("run app failed: %s", err)
}
}
func (s *webService) Stop() {
s.server.Shutdown(context.Background())
func (s *webService) registerRoute(e *gin.Engine) {
servants.RegisterWebServants(e)
}
func (s *webService) String() string {
@ -72,16 +62,22 @@ func newWebEngine() *gin.Engine {
return e
}
func NewWebService() Service {
e := newWebEngine()
servants.RegisterWebServants(e)
func newWebService() Service {
addr := conf.ServerSetting.HttpIp + ":" + conf.ServerSetting.HttpPort
server := httpServerFrom(addr, func() *httpServer {
engine := newWebEngine()
return &httpServer{
e: engine,
server: &http.Server{
Addr: addr,
Handler: engine,
ReadTimeout: conf.ServerSetting.ReadTimeout,
WriteTimeout: conf.ServerSetting.WriteTimeout,
MaxHeaderBytes: 1 << 20,
},
}
})
return &webService{
server: &http.Server{
Addr: conf.ServerSetting.HttpIp + ":" + conf.ServerSetting.HttpPort,
Handler: e,
ReadTimeout: conf.ServerSetting.ReadTimeout,
WriteTimeout: conf.ServerSetting.WriteTimeout,
MaxHeaderBytes: 1 << 20,
},
httpService: newBaseHttpService(server),
}
}

Loading…
Cancel
Save