1、配置文件使用个数进行配置,而不是使用数组。2、errorgroups模块使用参数列表进行注册。3、程序结束时defer关闭数据库。4、http模块使用syncpool来提高性能。5、httproute模块使用接口进行通信管道的传递。6、中间件增加回复数据的保存。7、rpc尽量支持可以使用unix配置。8、rpcserver可以自适应jsonrpc或者gobrpc。9、swarm模块进行重大调整,修改调度写成等待工作协程结束之后再结束(会发生死锁导致程序无法结束),修改调度协程无法执行defer函数问题,原因是main结束太快导致调度协程的defer来不及执行,使用函数选项来注入log。10、unis业务进行重大调整。11、所有皆采用面向对象的方式。
This commit is contained in:
parent
a297dfbb0f
commit
5a24eff7f1
@ -2,7 +2,7 @@ base:
|
|||||||
name: "avcnet_dash"
|
name: "avcnet_dash"
|
||||||
port: 8080
|
port: 8080
|
||||||
mode: "dev"
|
mode: "dev"
|
||||||
version: "v0.0.1"
|
version: "v0.1.0"
|
||||||
|
|
||||||
log:
|
log:
|
||||||
level: "debug"
|
level: "debug"
|
||||||
@ -14,7 +14,7 @@ log:
|
|||||||
database:
|
database:
|
||||||
# sqlite只需要指定db_name即可
|
# sqlite只需要指定db_name即可
|
||||||
type: "sqlite"
|
type: "sqlite"
|
||||||
db_name: "/tmp/data/sqlite/avcnet.db" # 如果是sqlite需要指定完整路径和文件名称
|
db_name: "/home/zs/tftpboot/cache/data/sqlite/avcnet.db" # 如果是sqlite需要指定完整路径和文件名称
|
||||||
# 其他远程数据库需要指定下面的内容
|
# 其他远程数据库需要指定下面的内容
|
||||||
user: "root"
|
user: "root"
|
||||||
password: "password"
|
password: "password"
|
||||||
@ -25,8 +25,12 @@ database:
|
|||||||
unis:
|
unis:
|
||||||
rpc:
|
rpc:
|
||||||
type: "json"
|
type: "json"
|
||||||
|
network: "tcp"
|
||||||
host: ""
|
host: ""
|
||||||
port: 5501
|
base_port: 5500
|
||||||
|
httpc:
|
||||||
|
clients: 5
|
||||||
|
instances: 2
|
||||||
|
|
||||||
# 使用令牌桶限流
|
# 使用令牌桶限流
|
||||||
rate:
|
rate:
|
||||||
|
@ -1,23 +1,25 @@
|
|||||||
package unisc
|
package unisc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"dashboard/dao/dadis/unisd"
|
|
||||||
"dashboard/models"
|
"dashboard/models"
|
||||||
|
"dashboard/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type httpHandle struct {
|
type httpHandle struct {
|
||||||
httpC chan *models.UnisHttpRequest
|
httpC []chan *models.UnisHttpRequest
|
||||||
|
pool sync.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newhttpHandle(httpc chan *models.UnisHttpRequest) *httpHandle {
|
func newhttpHandle(httpc []chan *models.UnisHttpRequest) *httpHandle {
|
||||||
res := new(httpHandle)
|
res := new(httpHandle)
|
||||||
|
|
||||||
res.httpC = httpc
|
res.httpC = httpc
|
||||||
|
res.pool.New = func() any { return new(models.UnisHttpRequest) }
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
@ -29,44 +31,59 @@ func httpSendWithExpire(httpc chan *models.UnisHttpRequest, data *models.UnisHtt
|
|||||||
select {
|
select {
|
||||||
case httpc <- data:
|
case httpc <- data:
|
||||||
case <-time.After(2 * time.Second):
|
case <-time.After(2 * time.Second):
|
||||||
return nil, models.ErrorTimeOut
|
return nil, models.ErrorSendTimeOut
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case resp := <-resc:
|
case resp := <-resc:
|
||||||
return resp, nil
|
return resp, nil
|
||||||
case <-time.After(2 * time.Second):
|
case <-time.After(2 * time.Second):
|
||||||
return nil, models.ErrorTimeOut
|
return nil, models.ErrorReciveTimeOut
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *httpHandle) stationConfig(c *gin.Context) error {
|
func (u *httpHandle) stationConfig(c *gin.Context) error {
|
||||||
|
log, _ := utils.GetLogFromContext(c)
|
||||||
|
|
||||||
config := new(models.StationConfigParams)
|
config := new(models.StationConfigParams)
|
||||||
if err := c.ShouldBindJSON(config); err != nil {
|
if err := c.ShouldBindJSON(config); err != nil {
|
||||||
|
log.Sugar().Errorf("stationConfig bind json err: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !config.StationConfig.ConfigType {
|
channel := c.GetInt(models.GinContextChannel)
|
||||||
res, ok := unisd.UnisDataGet(string(unisd.DadisKey_UnisStationInfo))
|
if channel > len(u.httpC)-1 {
|
||||||
if ok {
|
log.Sugar().Errorf("stationConfig channel err: %d", channel)
|
||||||
oldCfg := res.(*models.StationConfigParams)
|
return models.ErrorParamsErr
|
||||||
|
|
||||||
oldCfg.StationConfig.ConfigType = config.StationConfig.ConfigType
|
|
||||||
if reflect.DeepEqual(config, oldCfg) {
|
|
||||||
c.JSON(http.StatusOK, models.UnisHttpResponseOk)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
req := &models.UnisHttpRequest{
|
// if !config.StationConfig.ConfigType {
|
||||||
Id: models.UnisHttpUrl(c.Request.URL.String()).GetMsgId(),
|
// res, ok := unisd.UnisDataGet(unisd.DadisKey_UnisStationInfo.KeyWithChannel(channel))
|
||||||
Msg: config,
|
// if ok {
|
||||||
}
|
// oldCfg := res.(*models.StationConfigParams)
|
||||||
|
|
||||||
resp, err := httpSendWithExpire(u.httpC, req)
|
// oldCfg.StationConfig.ConfigType = config.StationConfig.ConfigType
|
||||||
|
// if reflect.DeepEqual(config, oldCfg) {
|
||||||
|
// log.Sugar().Infof("stationConfig is same")
|
||||||
|
// c.JSON(http.StatusOK, models.UnisHttpResponseOk)
|
||||||
|
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
req := u.pool.Get().(*models.UnisHttpRequest)
|
||||||
|
req.Id = models.UnisHttpUrl(c.Request.URL.String()).GetMsgId()
|
||||||
|
req.Msg = config
|
||||||
|
|
||||||
|
// req := &models.UnisHttpRequest{
|
||||||
|
// Id: models.UnisHttpUrl(c.Request.URL.String()).GetMsgId(),
|
||||||
|
// Msg: config,
|
||||||
|
// }
|
||||||
|
|
||||||
|
resp, err := httpSendWithExpire(u.httpC[channel], req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Sugar().Errorf("stationConfig send or recive err: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
@ -19,20 +20,29 @@ type HttpRoute struct {
|
|||||||
middleWare *middleWare
|
middleWare *middleWare
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHttpRoute(httpc chan *models.UnisHttpRequest) *HttpRoute {
|
type UnisHttpChanneler interface {
|
||||||
|
GetHttpChannel() chan *models.UnisHttpRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHttpRoute(httpc ...UnisHttpChanneler) *HttpRoute {
|
||||||
res := new(HttpRoute)
|
res := new(HttpRoute)
|
||||||
|
|
||||||
res.httpHandle = newhttpHandle(httpc)
|
var httpC []chan *models.UnisHttpRequest
|
||||||
|
for _, cha := range httpc {
|
||||||
|
httpC = append(httpC, cha.GetHttpChannel())
|
||||||
|
}
|
||||||
|
|
||||||
|
res.httpHandle = newhttpHandle(httpC)
|
||||||
res.middleWare = newmiddleWare()
|
res.middleWare = newmiddleWare()
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *HttpRoute) AddRoute(r *gin.Engine) {
|
func (u *HttpRoute) AddRoute(r *gin.Engine) {
|
||||||
unisr := r.Group("/api/unis")
|
unisr := r.Group(models.UnisHttpUrlPrefix)
|
||||||
unisr.Use(routes.ErrWapper(u.middleWare.GinCheckServerId), routes.ErrWapper(u.middleWare.GinStoreRequest))
|
unisr.Use(routes.ErrWapper(u.middleWare.ginCheckServerId), routes.ErrWapper(u.middleWare.ginStoreRequest))
|
||||||
{
|
{
|
||||||
unisr.POST("/config/v1/add", routes.ErrWapper(u.httpHandle.stationConfig))
|
unisr.POST(models.UNIS_HTTP_URL_CONFIG_ADD.Url(), routes.ErrWapper(u.httpHandle.stationConfig))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +53,7 @@ func newmiddleWare() *middleWare {
|
|||||||
return new(middleWare)
|
return new(middleWare)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *middleWare) GinCheckServerId(c *gin.Context) error {
|
func (m *middleWare) ginCheckServerId(c *gin.Context) error {
|
||||||
serverId := c.GetHeader("serverId")
|
serverId := c.GetHeader("serverId")
|
||||||
|
|
||||||
if serverId != serverId {
|
if serverId != serverId {
|
||||||
@ -71,14 +81,30 @@ func (m *middleWare) GinCheckServerId(c *gin.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *middleWare) GinStoreRequest(c *gin.Context) (err error) {
|
// bodyLogWriter 自定义响应写入器,用于捕获响应体
|
||||||
|
type bodyLogWriter struct {
|
||||||
|
gin.ResponseWriter
|
||||||
|
body *bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write 实现写入接口,同时写入缓冲区和原始响应
|
||||||
|
func (w *bodyLogWriter) Write(b []byte) (int, error) {
|
||||||
|
w.body.Write(b)
|
||||||
|
return w.ResponseWriter.Write(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteString 实现字符串写入接口(优化性能)
|
||||||
|
func (w *bodyLogWriter) WriteString(s string) (int, error) {
|
||||||
|
w.body.WriteString(s)
|
||||||
|
return w.ResponseWriter.WriteString(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *middleWare) ginStoreRequest(c *gin.Context) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Next()
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log, _ := utils.GetLogFromContext(c)
|
log, _ := utils.GetLogFromContext(c)
|
||||||
@ -87,18 +113,39 @@ func (m *middleWare) GinStoreRequest(c *gin.Context) (err error) {
|
|||||||
oldConf, _err := sqldb.ResFulDataGet(c.Request.Method, c.Request.URL.String(), channel)
|
oldConf, _err := sqldb.ResFulDataGet(c.Request.Method, c.Request.URL.String(), channel)
|
||||||
if _err != nil {
|
if _err != nil {
|
||||||
err = _err
|
err = _err
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyBytes, _err := io.ReadAll(c.Request.Body)
|
bodyBytes, _err := io.ReadAll(c.Request.Body)
|
||||||
if _err != nil {
|
if _err != nil {
|
||||||
err = _err
|
err = _err
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
|
c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
|
||||||
|
|
||||||
|
// 创建自定义响应写入器
|
||||||
|
blw := &bodyLogWriter{
|
||||||
|
body: bytes.NewBufferString(""),
|
||||||
|
ResponseWriter: c.Writer,
|
||||||
|
}
|
||||||
|
c.Writer = blw
|
||||||
|
|
||||||
|
c.Next()
|
||||||
|
|
||||||
|
// 获取响应信息
|
||||||
|
// statusCode := c.Writer.Status()
|
||||||
|
responseBody := blw.body.String()
|
||||||
|
|
||||||
|
// // 安全日志记录:限制大响应体
|
||||||
|
// logBody := responseBody
|
||||||
|
// if len(responseBody) > 1000 {
|
||||||
|
// logBody = responseBody[:1000] + "...[TRUNCATED]"
|
||||||
|
// }
|
||||||
|
|
||||||
if oldConf != string(bodyBytes) {
|
if oldConf != string(bodyBytes) {
|
||||||
log.Sugar().Info("The resful request is not equel local store")
|
log.Sugar().Info("The resful request is not equel local store so will save to database...")
|
||||||
if _err := sqldb.ResFulDataStore(c.Request.Method, c.Request.URL.String(), string(bodyBytes), channel); err != nil {
|
if _err := sqldb.ResFulDataStore(c.Request.Method, c.Request.URL.String(), responseBody, string(bodyBytes), channel); _err != nil {
|
||||||
err = _err
|
err = _err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,14 +153,14 @@ func (m *middleWare) GinStoreRequest(c *gin.Context) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *middleWare) GinWithUnisObject(unis *uniss.UnisStation) gin.HandlerFunc {
|
func (m *middleWare) ginWithUnisObject(unis *uniss.UnisStation) gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
c.Set(models.GinContextUnis, unis)
|
c.Set(models.GinContextUnis, unis)
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *middleWare) GetUnisObjectFromContext(c *gin.Context) (*uniss.UnisStation, error) {
|
func (m *middleWare) getUnisObjectFromContext(c *gin.Context) (*uniss.UnisStation, error) {
|
||||||
res, ok := c.Get(models.GinContextUnis)
|
res, ok := c.Get(models.GinContextUnis)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, models.ErrorInvalidData
|
return nil, models.ErrorInvalidData
|
||||||
@ -126,3 +173,10 @@ func (m *middleWare) GetUnisObjectFromContext(c *gin.Context) (*uniss.UnisStatio
|
|||||||
|
|
||||||
return unis, nil
|
return unis, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *middleWare) ginWithExpireTime(expire time.Duration) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
c.Set(models.GinContextExpire, expire)
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
package unisd
|
package unisd
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
type DadisKey string
|
type DadisKey string
|
||||||
|
|
||||||
|
func (d DadisKey) KeyWithChannel(channel int) string {
|
||||||
|
return fmt.Sprintf("%d:%s", channel, string(d))
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DadisKey_UnisSystemInfo DadisKey = "UnisSystemInfo"
|
DadisKey_UnisSystemInfo DadisKey = "UnisSystemInfo"
|
||||||
DadisKey_UnisStationInfo DadisKey = "UnisStationInfo"
|
DadisKey_UnisStationInfo DadisKey = "UnisStationInfo"
|
||||||
)
|
)
|
||||||
|
@ -6,13 +6,14 @@ const (
|
|||||||
createUserSql = `CREATE TABLE IF NOT EXISTS db_unis_aisub (userid TEXT NOT NULL,is_sub INTEGER,CONSTRAINT db_unis_aisub_pk PRIMARY KEY (userid));`
|
createUserSql = `CREATE TABLE IF NOT EXISTS db_unis_aisub (userid TEXT NOT NULL,is_sub INTEGER,CONSTRAINT db_unis_aisub_pk PRIMARY KEY (userid));`
|
||||||
|
|
||||||
createResStoreSql = `CREATE TABLE IF NOT EXISTS db_unis_res_store (
|
createResStoreSql = `CREATE TABLE IF NOT EXISTS db_unis_res_store (
|
||||||
key TEXT NOT NULL,
|
url TEXT NOT NULL,
|
||||||
value TEXT,
|
body TEXT,
|
||||||
|
response TEXT,
|
||||||
channel INTEGER,
|
channel INTEGER,
|
||||||
methord TEXT,
|
methord TEXT,
|
||||||
created_at TEXT NOT NULL DEFAULT (DATETIME('now', 'localtime')),
|
created_at TEXT NOT NULL DEFAULT (DATETIME('now', 'localtime')),
|
||||||
updated_at TEXT NOT NULL DEFAULT (DATETIME('now', 'localtime')),
|
updated_at TEXT NOT NULL DEFAULT (DATETIME('now', 'localtime')),
|
||||||
CONSTRAINT db_unis_res_pk PRIMARY KEY (key,channel,methord)
|
CONSTRAINT db_unis_res_pk PRIMARY KEY (url,channel,methord)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TRIGGER IF NOT EXISTS trigger_db_unis_res_store_updated_at AFTER UPDATE ON db_unis_res_store
|
CREATE TRIGGER IF NOT EXISTS trigger_db_unis_res_store_updated_at AFTER UPDATE ON db_unis_res_store
|
||||||
|
@ -5,10 +5,10 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ResFulDataStore(methord, key, value string, channel int) error {
|
func ResFulDataStore(methord, url, response, body string, channel int) error {
|
||||||
sqlStr := `INSERT OR REPLACE INTO db_unis_res_store(key,value,channel,methord) VALUES(?,?,?,?)`
|
sqlStr := `INSERT OR REPLACE INTO db_unis_res_store(url,body,channel,methord,response) VALUES(?,?,?,?,?)`
|
||||||
|
|
||||||
res, err := db.Exec(sqlStr, key, value, channel,methord)
|
res, err := db.Exec(sqlStr, url, body, channel, methord, response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -25,11 +25,11 @@ func ResFulDataStore(methord, key, value string, channel int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResFulDataGet(methord, key string, channel int) (string, error) {
|
func ResFulDataGet(methord, url string, channel int) (string, error) {
|
||||||
sqlStr := `SELECT value FROM db_unis_res_store WHERE key=? AND channel=? AND methord=?`
|
sqlStr := `SELECT body FROM db_unis_res_store WHERE url=? AND channel=? AND methord=?`
|
||||||
|
|
||||||
var res string
|
var res string
|
||||||
if err := db.Get(&res, sqlStr, key, channel, methord); err != nil {
|
if err := db.Get(&res, sqlStr, url, channel, methord); err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
38
main.go
38
main.go
@ -11,14 +11,25 @@ import (
|
|||||||
"dashboard/settings"
|
"dashboard/settings"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/fsnotify/fsnotify"
|
||||||
)
|
)
|
||||||
|
|
||||||
var config = flag.String("f", "./config/config.yaml", "config file path")
|
var config = flag.String("f", "./config/config.yaml", "config file path")
|
||||||
|
|
||||||
|
func callBack(e fsnotify.Event) {
|
||||||
|
// os.Exit(0)
|
||||||
|
// fmt.Println(e, os.Args)
|
||||||
|
|
||||||
|
// out, err := exec.Command("go", "run", os.Args[0]).Output()
|
||||||
|
|
||||||
|
// fmt.Println(out, err)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
sets := settings.New(settings.WithName(*config))
|
sets := settings.New(settings.WithName(*config), settings.WithCallBack(callBack))
|
||||||
|
|
||||||
log, err := logger.New(
|
log, err := logger.New(
|
||||||
logger.WithFileName(sets.LogConfig.Filename),
|
logger.WithFileName(sets.LogConfig.Filename),
|
||||||
@ -36,29 +47,42 @@ func main() {
|
|||||||
_ = log.Sync()
|
_ = log.Sync()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log.Info("Settings and log init ok")
|
log.Info("Settings and log init ok:)")
|
||||||
|
|
||||||
db, err := sqldb.NewDb(sets.SqlConfig)
|
db, err := sqldb.NewDb(sets.SqlConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Sugar().Panicf("New db error: %v", err)
|
log.Sugar().Panicf("New db error: %v", err)
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = db.GetDb().Close()
|
||||||
|
}()
|
||||||
|
|
||||||
err = sqldb.SqlDbInit(log, db)
|
err = sqldb.SqlDbInit(log, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Sugar().Panicf("New db error: %v", err)
|
log.Sugar().Panicf("New db error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
errwg := errgroups.NewErrGroup()
|
|
||||||
|
|
||||||
// r := routes.Setup(log, *sets.RateLimitConfig, *sets.JwtConfig)
|
// r := routes.Setup(log, *sets.RateLimitConfig, *sets.JwtConfig)
|
||||||
|
|
||||||
// listenAndServe(fmt.Sprintf(":%d", sets.BaseConfig.Port), r, log)
|
// listenAndServe(fmt.Sprintf(":%d", sets.BaseConfig.Port), r, log)
|
||||||
sunis := uniss.NewUnis(log, sets.UnisConfig)
|
var sunisa []errgroups.FuncWithErr
|
||||||
|
var route []unisc.UnisHttpChanneler
|
||||||
|
for index := range sets.UnisConfig.Instances {
|
||||||
|
sets.UnisConfig.Instances = index
|
||||||
|
unis, err := uniss.NewUnis(log, sets.UnisConfig)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
sunisa = append(sunisa, unis)
|
||||||
|
route = append(route, unis)
|
||||||
|
}
|
||||||
|
|
||||||
|
errwg := errgroups.NewErrGroup()
|
||||||
|
|
||||||
errwg.Add(routes.NewRouter(fmt.Sprintf(":%d", sets.BaseConfig.Port),
|
errwg.Add(routes.NewRouter(fmt.Sprintf(":%d", sets.BaseConfig.Port),
|
||||||
log, *sets.RateLimitConfig, *sets.JwtConfig,
|
log, *sets.RateLimitConfig, *sets.JwtConfig,
|
||||||
unisc.NewHttpRoute(sunis.GetHttpChannel())))
|
unisc.NewHttpRoute(route...)))
|
||||||
errwg.Add(sunis)
|
errwg.Add(sunisa...)
|
||||||
|
|
||||||
log.Sugar().Fatalln(errwg.Run(context.Background()))
|
log.Sugar().Fatalln(errwg.Run(context.Background()))
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ const (
|
|||||||
GinContextChannel = "channel"
|
GinContextChannel = "channel"
|
||||||
GinContextServerId = "serverid"
|
GinContextServerId = "serverid"
|
||||||
GinContextUnis = "unis"
|
GinContextUnis = "unis"
|
||||||
|
GinContextExpire = "expire"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -18,10 +19,12 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrorInvalidData = errors.New("no such value")
|
ErrorInvalidData = errors.New("no such value")
|
||||||
ErrorPasswordErr = errors.New("user or password invalid")
|
ErrorPasswordErr = errors.New("user or password invalid")
|
||||||
ErrorSqlInitErr = errors.New("database init err")
|
ErrorSqlInitErr = errors.New("database init err")
|
||||||
ErrorTimeOut = errors.New("time out")
|
ErrorSendTimeOut = errors.New("send time out")
|
||||||
|
ErrorReciveTimeOut = errors.New("recive time out")
|
||||||
|
ErrorParamsErr = errors.New("invalid params")
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
type UnisHttpRequest struct {
|
type UnisHttpRequest struct {
|
||||||
ResC chan *UnisHttpResponse
|
ResC chan *UnisHttpResponse
|
||||||
Id string
|
Channel int
|
||||||
Msg interface{}
|
Id string
|
||||||
|
Msg interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type UnisHttpResponse struct {
|
type UnisHttpResponse struct {
|
||||||
@ -12,8 +15,28 @@ type UnisHttpResponse struct {
|
|||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UnisHttpClientRequest struct {
|
||||||
|
Url string
|
||||||
|
Methord string
|
||||||
|
Id string
|
||||||
|
Msg interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnisHttpClientResponse struct {
|
||||||
|
Url string
|
||||||
|
Methord string
|
||||||
|
Id string
|
||||||
|
Msg interface{}
|
||||||
|
}
|
||||||
|
|
||||||
type UnisHttpUrl string
|
type UnisHttpUrl string
|
||||||
|
|
||||||
|
const UnisHttpUrlPrefix = "/api/unis"
|
||||||
|
|
||||||
|
func (u UnisHttpUrl) Url() string {
|
||||||
|
return strings.TrimPrefix(string(u), UnisHttpUrlPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
UNIS_HTTP_URL_CONFIG_ADD UnisHttpUrl = "/api/unis/config/v1/add"
|
UNIS_HTTP_URL_CONFIG_ADD UnisHttpUrl = "/api/unis/config/v1/add"
|
||||||
)
|
)
|
||||||
|
@ -2,22 +2,22 @@ package models
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
const rpcNamePrefix = "UnisRpcService"
|
const rpcNamePrefix = "RpcServerStub"
|
||||||
|
|
||||||
type UnisRpcMethod string
|
type UnisRpcMethod string
|
||||||
|
|
||||||
func (m UnisRpcMethod)Methord()string{
|
func (m UnisRpcMethod) Methord() string {
|
||||||
return fmt.Sprintf("%s.%s",rpcNamePrefix,string(m))
|
return fmt.Sprintf("%s.%s", rpcNamePrefix, string(m))
|
||||||
}
|
}
|
||||||
|
|
||||||
const(
|
const (
|
||||||
UnisStationConfig UnisRpcMethod = "Config"
|
UnisStationConfig UnisRpcMethod = "Config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UnisRpcRequest struct{
|
type UnisRpcRequest struct {
|
||||||
Id string
|
Id string
|
||||||
}
|
}
|
||||||
|
|
||||||
type UnisRpcResponse struct{
|
type UnisRpcResponse struct {
|
||||||
Id string
|
Id string
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
type Dadis struct {
|
type Dadis struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
store map[string]*item
|
store map[string]*item
|
||||||
observe *observe.AsyncEventBus
|
observe *observe.SyncEventBus
|
||||||
}
|
}
|
||||||
|
|
||||||
type item struct {
|
type item struct {
|
||||||
@ -21,7 +21,7 @@ type item struct {
|
|||||||
func NewDadis() *Dadis {
|
func NewDadis() *Dadis {
|
||||||
return &Dadis{
|
return &Dadis{
|
||||||
store: make(map[string]*item),
|
store: make(map[string]*item),
|
||||||
observe: observe.NewAsyncEventBus(),
|
observe: observe.NewSyncEventBus(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ package errgroups
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"dashboard/utils"
|
"dashboard/utils"
|
||||||
"fmt"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,6 +17,7 @@ type ErrGroupFunc struct {
|
|||||||
|
|
||||||
type FuncWithErrFunc func(context.Context) error
|
type FuncWithErrFunc func(context.Context) error
|
||||||
|
|
||||||
|
// 注意使用func时,如果想要对数组对象执行多个函数,不可以使用此种方法,因为函数名都是一样的,map里面会被替换。此种场景需要使用接口的方式。
|
||||||
func NewErrGroupFunc() *ErrGroupFunc {
|
func NewErrGroupFunc() *ErrGroupFunc {
|
||||||
return &ErrGroupFunc{
|
return &ErrGroupFunc{
|
||||||
funs: make(map[string]FuncWithErrFunc),
|
funs: make(map[string]FuncWithErrFunc),
|
||||||
@ -33,8 +34,8 @@ func (e *ErrGroupFunc) Run(ctx context.Context) error {
|
|||||||
fn := fn
|
fn := fn
|
||||||
name := name
|
name := name
|
||||||
e.wg.Go(func() error {
|
e.wg.Go(func() error {
|
||||||
defer fmt.Printf("func: %s stop\n", name)
|
defer zap.L().Sugar().Warnf("func: %s stop", name)
|
||||||
fmt.Printf("func: %s runing...\n", name)
|
zap.L().Sugar().Infof("func: %s runing...", name)
|
||||||
return fn(ctx)
|
return fn(ctx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -46,22 +47,24 @@ func (e *ErrGroupFunc) Run(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ErrGroupFunc) Add(fn FuncWithErrFunc) {
|
func (e *ErrGroupFunc) Add(fn ...FuncWithErrFunc) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
fnStr := utils.GetFuncName(fn)
|
for _, f := range fn {
|
||||||
|
fnStr := utils.GetFuncName(f)
|
||||||
e.funs[fnStr] = fn
|
e.funs[fnStr] = f
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ErrGroupFunc) Del(fn FuncWithErrFunc) {
|
func (e *ErrGroupFunc) Del(fn ...FuncWithErrFunc) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
fnStr := utils.GetFuncName(fn)
|
for _, f := range fn {
|
||||||
|
fnStr := utils.GetFuncName(f)
|
||||||
delete(e.funs, fnStr)
|
delete(e.funs, fnStr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ErrGroup struct {
|
type ErrGroup struct {
|
||||||
@ -87,8 +90,11 @@ func (e *ErrGroup) Run(ctx context.Context) error {
|
|||||||
e.wg, ctx = errgroup.WithContext(ctx)
|
e.wg, ctx = errgroup.WithContext(ctx)
|
||||||
|
|
||||||
for fn := range e.funs {
|
for fn := range e.funs {
|
||||||
fn := fn
|
fn := fn // shadow
|
||||||
|
name := utils.GetInterfaceName(fn)
|
||||||
e.wg.Go(func() error {
|
e.wg.Go(func() error {
|
||||||
|
defer zap.L().Sugar().Warnf("Object: %s stop", name)
|
||||||
|
zap.L().Sugar().Infof("Object: %s runing...", name)
|
||||||
return fn.Run(ctx)
|
return fn.Run(ctx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -100,16 +106,20 @@ func (e *ErrGroup) Run(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ErrGroup) Add(fn FuncWithErr) {
|
func (e *ErrGroup) Add(fn ...FuncWithErr) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
e.funs[fn] = struct{}{}
|
for _, f := range fn {
|
||||||
|
e.funs[f] = struct{}{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ErrGroup) Del(fn FuncWithErr) {
|
func (e *ErrGroup) Del(fn ...FuncWithErr) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
delete(e.funs, fn)
|
for _, f := range fn {
|
||||||
|
delete(e.funs, f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
26
pkg/rpcsup/client.go
Normal file
26
pkg/rpcsup/client.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package rpcsup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
"net/rpc"
|
||||||
|
"net/rpc/jsonrpc"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RpcClient(conf *RpcConfig) (*rpc.Client, error) {
|
||||||
|
if strings.Contains(conf.Typec, "json") {
|
||||||
|
dial, err := net.Dial(conf.Network, conf.Address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonrpc.NewClient(dial), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(conf.Typec, "grpc") {
|
||||||
|
return nil, errors.New("currently not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
return rpc.Dial(conf.Network, conf.Address)
|
||||||
|
}
|
@ -1,74 +0,0 @@
|
|||||||
package rpcsup
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"dashboard/logger"
|
|
||||||
"errors"
|
|
||||||
"net"
|
|
||||||
"net/rpc"
|
|
||||||
"net/rpc/jsonrpc"
|
|
||||||
|
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
)
|
|
||||||
|
|
||||||
func JsonServer(ctx context.Context, log *logger.Logger, address string, service ...interface{}) error {
|
|
||||||
for _, re := range service {
|
|
||||||
if err := rpc.Register(re); err != nil {
|
|
||||||
log.Sugar().Error(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listen, err := net.Listen("tcp", address)
|
|
||||||
if err != nil {
|
|
||||||
log.Sugar().Error(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Sugar().Infof("Rpc server listen on: %s", address)
|
|
||||||
|
|
||||||
wg, ctxx := errgroup.WithContext(ctx)
|
|
||||||
|
|
||||||
wg.Go(func() error {
|
|
||||||
for {
|
|
||||||
accept, err := listen.Accept()
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, net.ErrClosed) {
|
|
||||||
log.Sugar().Error(err)
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
log.Sugar().Error(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
go jsonrpc.ServeConn(accept)
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
|
|
||||||
wg.Go(func() error {
|
|
||||||
<-ctxx.Done()
|
|
||||||
log.Sugar().Errorf("Unis Rpc Server cancel by ctx")
|
|
||||||
listen.Close()
|
|
||||||
return ctxx.Err()
|
|
||||||
})
|
|
||||||
|
|
||||||
if err := wg.Wait(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func JsonClient(log *logger.Logger, address string) (*rpc.Client, error) {
|
|
||||||
dial, err := net.Dial("tcp", address)
|
|
||||||
if err != nil {
|
|
||||||
log.Sugar().Error(err)
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return jsonrpc.NewClient(dial), nil
|
|
||||||
}
|
|
103
pkg/rpcsup/rpcsup.go
Normal file
103
pkg/rpcsup/rpcsup.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package rpcsup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
"net/rpc"
|
||||||
|
"net/rpc/jsonrpc"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RpcServicer interface {
|
||||||
|
Name() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type RpcService struct {
|
||||||
|
rpc *rpc.Server
|
||||||
|
listen net.Listener
|
||||||
|
handler func(net.Conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
type RpcConfig struct {
|
||||||
|
Typec string
|
||||||
|
Network string
|
||||||
|
Address string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRpcService(conf *RpcConfig) (res *RpcService, err error) {
|
||||||
|
res = new(RpcService)
|
||||||
|
|
||||||
|
res.rpc = rpc.NewServer()
|
||||||
|
res.listen, err = net.Listen(conf.Network, conf.Address)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(conf.Typec, "json") {
|
||||||
|
res.handler = func(c net.Conn) {
|
||||||
|
res.rpc.ServeCodec(jsonrpc.NewServerCodec(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(conf.Typec, "grpc") {
|
||||||
|
return nil, errors.New("currently not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
res.handler = func(c net.Conn) {
|
||||||
|
res.rpc.ServeConn(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RpcService) Register(service ...interface{}) error {
|
||||||
|
for _, ser := range service {
|
||||||
|
if nser, ok := ser.(RpcServicer); ok {
|
||||||
|
if err := r.rpc.RegisterName(nser.Name(), nser); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.rpc.Register(ser); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RpcService) Run(ctx context.Context) error {
|
||||||
|
wg, ctxx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
|
wg.Go(func() error {
|
||||||
|
for {
|
||||||
|
accept, err := r.listen.Accept()
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, net.ErrClosed) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
go r.handler(accept)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
wg.Go(func() error {
|
||||||
|
<-ctxx.Done()
|
||||||
|
r.listen.Close()
|
||||||
|
return ctxx.Err()
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := wg.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
22
pkg/swarm/option.go
Normal file
22
pkg/swarm/option.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package swarm
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
|
type options struct {
|
||||||
|
log *log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
type Option func(*options)
|
||||||
|
|
||||||
|
func WithLog(log *log.Logger) Option {
|
||||||
|
return func(o *options) {
|
||||||
|
o.log = log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func(o *options)repire(){
|
||||||
|
if o.log == nil{
|
||||||
|
o.log = log.Default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
69
pkg/swarm/scheduler.go
Normal file
69
pkg/swarm/scheduler.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package swarm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type defaultScheduler[T any] struct {
|
||||||
|
worker chan chan T
|
||||||
|
request chan T
|
||||||
|
log *log.Logger
|
||||||
|
calFn context.CancelFunc
|
||||||
|
ctx context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func newdefaultScheduler[T any](log *log.Logger) *defaultScheduler[T] {
|
||||||
|
res := new(defaultScheduler[T])
|
||||||
|
|
||||||
|
res.worker = make(chan chan T)
|
||||||
|
res.request = make(chan T)
|
||||||
|
res.log = log
|
||||||
|
res.ctx, res.calFn = context.WithCancel(context.TODO())
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *defaultScheduler[T]) Submit(req T) {
|
||||||
|
s.request <- req
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *defaultScheduler[T]) Done(worker chan T) {
|
||||||
|
s.worker <- worker
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *defaultScheduler[T]) GenChannel() chan T {
|
||||||
|
return make(chan T)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *defaultScheduler[T]) Stop() {
|
||||||
|
s.calFn()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *defaultScheduler[T]) Run() error {
|
||||||
|
var workers []chan T
|
||||||
|
var requests []T
|
||||||
|
|
||||||
|
for {
|
||||||
|
var work chan T
|
||||||
|
var req T
|
||||||
|
|
||||||
|
if len(workers) > 0 && len(requests) > 0 {
|
||||||
|
work = workers[0]
|
||||||
|
req = requests[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-s.ctx.Done():
|
||||||
|
s.log.Printf("%sScheduler: %p down...", logPrefix, s)
|
||||||
|
return s.ctx.Err()
|
||||||
|
case w := <-s.worker:
|
||||||
|
workers = append(workers, w)
|
||||||
|
case r := <-s.request:
|
||||||
|
requests = append(requests, r)
|
||||||
|
case work <- req:
|
||||||
|
workers = workers[1:]
|
||||||
|
requests = requests[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
117
pkg/swarm/swarm.go
Normal file
117
pkg/swarm/swarm.go
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
package swarm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"dashboard/pkg/errgroups"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
const logPrefix = "[swarm] "
|
||||||
|
|
||||||
|
type Swarm[T any] struct {
|
||||||
|
scheduler Scheduler[T]
|
||||||
|
bees []*beeJob[T]
|
||||||
|
opts options
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSwarm[T any](num int, work func(T) error, opts ...Option) *Swarm[T] {
|
||||||
|
res := new(Swarm[T])
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&res.opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
res.opts.repire()
|
||||||
|
|
||||||
|
res.scheduler = newdefaultScheduler[T](res.opts.log)
|
||||||
|
|
||||||
|
for index := range num {
|
||||||
|
res.bees = append(res.bees, &beeJob[T]{
|
||||||
|
done: func(c chan T) { res.scheduler.Done(c) },
|
||||||
|
wc: res.scheduler.GenChannel(),
|
||||||
|
do: work,
|
||||||
|
index: index,
|
||||||
|
log: res.opts.log,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
res.opts.log.Printf("%sStart bees number: %d.", logPrefix, len(res.bees))
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
type beeJob[T any] struct {
|
||||||
|
done func(chan T)
|
||||||
|
wc chan T
|
||||||
|
do func(T) error
|
||||||
|
index int
|
||||||
|
log *log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beeJob[T]) Run(ctx context.Context) error {
|
||||||
|
for {
|
||||||
|
b.done(b.wc)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
b.log.Printf("Bee num: %d,down\n", b.index)
|
||||||
|
return ctx.Err()
|
||||||
|
case req := <-b.wc:
|
||||||
|
if err := b.do(req); err != nil {
|
||||||
|
b.log.Printf("%sBee num: %d, do the work error: %v", logPrefix, b.index, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
b.log.Printf("%sBee num: %d, do the work success:)", logPrefix, b.index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Scheduler[T any] interface {
|
||||||
|
Run() error
|
||||||
|
Submit(T)
|
||||||
|
Done(chan T)
|
||||||
|
GenChannel() chan T
|
||||||
|
Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Swarm[T]) Submit(sub T) {
|
||||||
|
s.scheduler.Submit(sub)
|
||||||
|
}
|
||||||
|
|
||||||
|
// implement FuncWithErr interface
|
||||||
|
func (s *Swarm[T]) Run(ctx context.Context) error {
|
||||||
|
wgs, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
|
wgs.Go(func() error {
|
||||||
|
defer s.scheduler.Stop()
|
||||||
|
|
||||||
|
ewgs := errgroups.NewErrGroup()
|
||||||
|
|
||||||
|
// // 可以保证bee结束,但是不能保证scheduler正常退出
|
||||||
|
// schectx, cancel := context.WithCancel(context.TODO())
|
||||||
|
// defer cancel()
|
||||||
|
|
||||||
|
// go s.scheduler.Run(schectx)
|
||||||
|
|
||||||
|
// ewgs.Add(s.scheduler) // 结束的比bee早,导致bee可能会被永久阻塞,导致进程不能退出。
|
||||||
|
|
||||||
|
for _, bee := range s.bees {
|
||||||
|
ewgs.Add(bee)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ewgs.Run(ctx)
|
||||||
|
})
|
||||||
|
|
||||||
|
wgs.Go(func() error {
|
||||||
|
return s.scheduler.Run()
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := wgs.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
32
pkg/swarm/swarm_test.go
Normal file
32
pkg/swarm/swarm_test.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package swarm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testwork(req string) error {
|
||||||
|
fmt.Println(req)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_swarm(t *testing.T) {
|
||||||
|
swarm := NewSwarm(10, testwork)
|
||||||
|
|
||||||
|
for range 10 {
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
swarm.scheduler.Submit("nihao")
|
||||||
|
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, calFn := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
|
defer calFn()
|
||||||
|
swarm.Run(ctx)
|
||||||
|
}
|
@ -4,21 +4,24 @@ import (
|
|||||||
"dashboard/dao/dadis/unisd"
|
"dashboard/dao/dadis/unisd"
|
||||||
"dashboard/models"
|
"dashboard/models"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type commonService struct {
|
type commonService struct {
|
||||||
rpcClients *rpcClients
|
comm *communicateService
|
||||||
}
|
}
|
||||||
|
|
||||||
func newcommonService(http *httpHandle) *commonService {
|
func newcommonService(comm *communicateService) *commonService {
|
||||||
res := new(commonService)
|
res := new(commonService)
|
||||||
|
|
||||||
http.pushHandle(string(models.UNIS_HTTP_ID_CONFIG_ADD), res.stationConfig)
|
res.comm = comm
|
||||||
|
|
||||||
|
res.comm.httpServerHandler.pushHandle(string(models.UNIS_HTTP_ID_CONFIG_ADD), res.stationConfig)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *commonService) stationConfig(reqest *models.UnisHttpRequest) (*models.UnisHttpResponse, error) {
|
func (c *commonService) stationConfig(reqest *models.UnisHttpRequest, respons *models.UnisHttpResponse) error {
|
||||||
req := reqest.Msg.(*models.StationConfigParams)
|
req := reqest.Msg.(*models.StationConfigParams)
|
||||||
fmt.Println(req)
|
fmt.Println(req)
|
||||||
|
|
||||||
@ -32,16 +35,23 @@ func (c *commonService) stationConfig(reqest *models.UnisHttpRequest) (*models.U
|
|||||||
addres = append(addres, add)
|
addres = append(addres, add)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.rpcClients.flushRpcClients(addres)
|
c.comm.rpcClientStub.flushRpcClients(addres)
|
||||||
|
|
||||||
fmt.Println(c.rpcClients.getConfig(addres[0].id, models.UnisRpcRequest{Id: "zhangshuo"}))
|
fmt.Println(c.comm.rpcClientStub.getConfig(addres[0].id, models.UnisRpcRequest{Id: "zhangshuo"}))
|
||||||
|
|
||||||
res := &models.UnisHttpResponse{
|
// res := &models.UnisHttpResponse{
|
||||||
Code: int(models.CodeSuccess),
|
// Code: int(models.CodeSuccess),
|
||||||
Msg: "config ok",
|
// Msg: "config ok",
|
||||||
}
|
// }
|
||||||
|
respons.Code = int(models.CodeSuccess)
|
||||||
|
respons.Msg = "config ok"
|
||||||
|
|
||||||
unisd.UnisDataSet(string(unisd.DadisKey_UnisStationInfo), req, 0)
|
unisd.UnisDataSet(unisd.DadisKey_UnisStationInfo.KeyWithChannel(reqest.Channel), req, 0)
|
||||||
|
|
||||||
return res, nil
|
c.comm.httpClientHandler.curl(&models.UnisHttpClientRequest{
|
||||||
|
Url: "http://192.168.177.7:8080/api/unis/source-list/v1/update",
|
||||||
|
Methord: http.MethodGet,
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
54
services/uniss/communicate.go
Normal file
54
services/uniss/communicate.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package uniss
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"dashboard/pkg/errgroups"
|
||||||
|
"dashboard/pkg/rpcsup"
|
||||||
|
"dashboard/settings"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type communicateService struct {
|
||||||
|
rpcClientStub *rpcClientStub
|
||||||
|
rpcService *rpcsup.RpcService
|
||||||
|
httpServerHandler *httpServerHandler
|
||||||
|
httpClientHandler *httpClientHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func newcommunicateService(conf *settings.UnisConfig) (res *communicateService, err error) {
|
||||||
|
res = new(communicateService)
|
||||||
|
|
||||||
|
var rpcConf = &rpcsup.RpcConfig{
|
||||||
|
Typec: conf.RpcConfig.Type,
|
||||||
|
Network: conf.RpcConfig.Network,
|
||||||
|
Address: fmt.Sprintf("%s:%d", conf.RpcConfig.Host, conf.RpcConfig.BasePort+conf.Instances)}
|
||||||
|
|
||||||
|
res.rpcService, err = rpcsup.NewRpcService(rpcConf)
|
||||||
|
if err != nil {
|
||||||
|
log.Sugar().Errorf("New rpc service error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Sugar().Infof("New rpc service ok type: %s, network: %s, address: %s", rpcConf.Typec, rpcConf.Network, rpcConf.Address)
|
||||||
|
|
||||||
|
err = res.rpcService.Register(newrpcServerStub())
|
||||||
|
if err != nil {
|
||||||
|
log.Sugar().Errorf("Rpc service register error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Sugar().Infof("Rpc service register all ok")
|
||||||
|
|
||||||
|
res.httpServerHandler = newhttpServerHandler()
|
||||||
|
res.rpcClientStub = newRpcClients(conf.RpcConfig)
|
||||||
|
res.httpClientHandler = newhttpClientHandle(conf.HttpClientConfig.Clients)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *communicateService) Run(ctx context.Context) error {
|
||||||
|
ewgs := errgroups.NewErrGroup()
|
||||||
|
|
||||||
|
ewgs.Add(c.rpcService)
|
||||||
|
ewgs.Add(c.httpClientHandler.swarm)
|
||||||
|
|
||||||
|
return ewgs.Run(ctx)
|
||||||
|
}
|
20
services/uniss/datacenter.go
Normal file
20
services/uniss/datacenter.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package uniss
|
||||||
|
|
||||||
|
import (
|
||||||
|
"dashboard/pkg/dadis"
|
||||||
|
"dashboard/settings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type dataCenterService struct {
|
||||||
|
conf *settings.UnisConfig
|
||||||
|
dataMap *dadis.Dadis
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDataCenterService(conf *settings.UnisConfig) *dataCenterService {
|
||||||
|
res := new(dataCenterService)
|
||||||
|
|
||||||
|
res.conf = conf
|
||||||
|
res.dataMap = dadis.NewDadis()
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
72
services/uniss/httpclienthandle.go
Normal file
72
services/uniss/httpclienthandle.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package uniss
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"dashboard/dao/sqldb"
|
||||||
|
"dashboard/models"
|
||||||
|
"dashboard/pkg/swarm"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type httpClientHandler struct {
|
||||||
|
swarm *swarm.Swarm[*models.UnisHttpClientRequest]
|
||||||
|
httpC chan *models.UnisHttpClientResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
func newhttpClientHandle(clients int) *httpClientHandler {
|
||||||
|
res := new(httpClientHandler)
|
||||||
|
res.swarm = swarm.NewSwarm(clients, res.doRequest, swarm.WithLog(zap.NewStdLog(log.Logger)))
|
||||||
|
res.httpC = make(chan *models.UnisHttpClientResponse)
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *httpClientHandler) curl(msg *models.UnisHttpClientRequest) {
|
||||||
|
c.swarm.Submit(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *httpClientHandler) doRequest(req *models.UnisHttpClientRequest) error {
|
||||||
|
body, err := json.Marshal(req.Msg)
|
||||||
|
fmt.Println(string(body), err)
|
||||||
|
|
||||||
|
reqs, err := http.NewRequest(req.Methord, req.Url, bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
reqs.Header.Add("Content-type", "application/json;charset=utf-8")
|
||||||
|
|
||||||
|
client := http.Client{}
|
||||||
|
resp, err := client.Do(reqs)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
msg, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := sqldb.ResFulDataStore(req.Methord, req.Url, string(body), string(msg), 0); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &models.UnisHttpClientResponse{
|
||||||
|
Id: req.Id,
|
||||||
|
Methord: req.Methord,
|
||||||
|
Msg: msg,
|
||||||
|
}
|
||||||
|
|
||||||
|
c.httpC <- response
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,66 +0,0 @@
|
|||||||
package uniss
|
|
||||||
|
|
||||||
import (
|
|
||||||
"dashboard/models"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type httpHandle struct {
|
|
||||||
httpC chan *models.UnisHttpRequest
|
|
||||||
mu sync.RWMutex
|
|
||||||
mapFn map[string]HttpHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
type HttpHandler func(*models.UnisHttpRequest) (*models.UnisHttpResponse, error)
|
|
||||||
|
|
||||||
func newhttpHandle() *httpHandle {
|
|
||||||
res := new(httpHandle)
|
|
||||||
|
|
||||||
res.httpC = make(chan *models.UnisHttpRequest)
|
|
||||||
res.mapFn = make(map[string]HttpHandler)
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *httpHandle) httpHandle(msg *models.UnisHttpRequest) {
|
|
||||||
var res *models.UnisHttpResponse
|
|
||||||
resC := msg.ResC
|
|
||||||
defer func() {
|
|
||||||
if resC != nil {
|
|
||||||
resC <- res
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
fn, ok := u.getHandle(msg.Id)
|
|
||||||
if ok {
|
|
||||||
if re, err := fn(msg); err == nil {
|
|
||||||
res = re
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *httpHandle) pushHandle(key string, handle HttpHandler) {
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
|
|
||||||
u.mapFn[key] = handle
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *httpHandle) delHandle(key string) {
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
|
|
||||||
delete(u.mapFn, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *httpHandle) getHandle(key string) (HttpHandler, bool) {
|
|
||||||
u.mu.RLock()
|
|
||||||
defer u.mu.RUnlock()
|
|
||||||
|
|
||||||
res, ok := u.mapFn[key]
|
|
||||||
if !ok {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, ok
|
|
||||||
}
|
|
68
services/uniss/httpserverhandle.go
Normal file
68
services/uniss/httpserverhandle.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package uniss
|
||||||
|
|
||||||
|
import (
|
||||||
|
"dashboard/models"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type httpServerHandler struct {
|
||||||
|
httpC chan *models.UnisHttpRequest
|
||||||
|
mu sync.RWMutex
|
||||||
|
mapFn map[string]HttpServerHandlerFunc
|
||||||
|
pool sync.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
type HttpServerHandlerFunc func(*models.UnisHttpRequest, *models.UnisHttpResponse) error
|
||||||
|
|
||||||
|
func newhttpServerHandler() *httpServerHandler {
|
||||||
|
res := new(httpServerHandler)
|
||||||
|
|
||||||
|
res.httpC = make(chan *models.UnisHttpRequest)
|
||||||
|
res.mapFn = make(map[string]HttpServerHandlerFunc)
|
||||||
|
res.pool.New = func() any { return new(models.UnisHttpResponse) }
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *httpServerHandler) httpHandle(msg *models.UnisHttpRequest) {
|
||||||
|
res := u.pool.Get().(*models.UnisHttpResponse)
|
||||||
|
resC := msg.ResC
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if resC != nil {
|
||||||
|
resC <- res
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
fn, ok := u.getHandle(msg.Id)
|
||||||
|
if ok {
|
||||||
|
if err := fn(msg, res); err == nil {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *httpServerHandler) pushHandle(key string, handle HttpServerHandlerFunc) {
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
|
||||||
|
u.mapFn[key] = handle
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *httpServerHandler) delHandle(key string) {
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
|
||||||
|
delete(u.mapFn, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *httpServerHandler) getHandle(key string) (HttpServerHandlerFunc, bool) {
|
||||||
|
u.mu.RLock()
|
||||||
|
defer u.mu.RUnlock()
|
||||||
|
|
||||||
|
res, ok := u.mapFn[key]
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, ok
|
||||||
|
}
|
@ -1,45 +1,54 @@
|
|||||||
package uniss
|
package uniss
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// 1.data center object 2.swarm stop after scheduler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"dashboard/logger"
|
"dashboard/logger"
|
||||||
"dashboard/models"
|
"dashboard/models"
|
||||||
"dashboard/pkg/errgroups"
|
"dashboard/pkg/errgroups"
|
||||||
"dashboard/settings"
|
"dashboard/settings"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var log *logger.Logger
|
||||||
|
|
||||||
type UnisStation struct {
|
type UnisStation struct {
|
||||||
log *logger.Logger
|
commonService *commonService
|
||||||
conf *settings.UnisConfig
|
communicateService *communicateService
|
||||||
httpHandle *httpHandle
|
dataCenterService *dataCenterService
|
||||||
commonService *commonService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUnis(log *logger.Logger, conf *settings.UnisConfig) *UnisStation {
|
func NewUnis(_log *logger.Logger, conf *settings.UnisConfig) (res *UnisStation, err error) {
|
||||||
res := new(UnisStation)
|
res = new(UnisStation)
|
||||||
|
log = _log
|
||||||
|
|
||||||
res.log = log
|
res.dataCenterService = newDataCenterService(conf)
|
||||||
res.conf = conf
|
res.communicateService, err = newcommunicateService(conf)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
res.httpHandle = newhttpHandle()
|
res.commonService = newcommonService(res.communicateService)
|
||||||
res.commonService = newcommonService(res.httpHandle)
|
|
||||||
res.commonService.rpcClients = newRpcClients(log, conf.RpcConfig.Port)
|
|
||||||
|
|
||||||
return res
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UnisStation) GetHttpChannel() chan *models.UnisHttpRequest {
|
func (u *UnisStation) GetHttpChannel() chan *models.UnisHttpRequest {
|
||||||
return u.httpHandle.httpC
|
return u.communicateService.httpServerHandler.httpC
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UnisStation) mesageHandle(ctx context.Context) error {
|
func (u *UnisStation) mainthread(ctx context.Context) error {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
u.log.Error("Unis mesageHandle cancel by ctx")
|
log.Error("Unis mesageHandle cancel by ctx")
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
case httpMsg := <-u.httpHandle.httpC:
|
case httpMsg := <-u.communicateService.httpServerHandler.httpC:
|
||||||
u.httpHandle.httpHandle(httpMsg)
|
u.communicateService.httpServerHandler.httpHandle(httpMsg)
|
||||||
|
case httpc := <-u.communicateService.httpClientHandler.httpC:
|
||||||
|
fmt.Println(string(httpc.Msg.([]byte)))
|
||||||
// default:
|
// default:
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,12 +56,10 @@ func (u *UnisStation) mesageHandle(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *UnisStation) Run(ctx context.Context) error {
|
func (u *UnisStation) Run(ctx context.Context) error {
|
||||||
rpc := newUnisRpcServer(u.log, u.conf.RpcConfig)
|
|
||||||
|
|
||||||
ewgs := errgroups.NewErrGroupFunc()
|
ewgs := errgroups.NewErrGroupFunc()
|
||||||
|
|
||||||
ewgs.Add(rpc.rpcListenAndServe)
|
ewgs.Add(u.communicateService.Run)
|
||||||
ewgs.Add(u.mesageHandle)
|
ewgs.Add(u.mainthread)
|
||||||
|
|
||||||
return ewgs.Run(ctx)
|
return ewgs.Run(ctx)
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,38 @@
|
|||||||
package uniss
|
package uniss
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"dashboard/logger"
|
|
||||||
"dashboard/models"
|
"dashboard/models"
|
||||||
"dashboard/pkg/rpcsup"
|
"dashboard/pkg/rpcsup"
|
||||||
|
"dashboard/settings"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/rpc"
|
"net/rpc"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type rpcClients struct {
|
// Called by someone else
|
||||||
*logger.Logger
|
type rpcClientStub struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
conf *settings.RpcConfig
|
||||||
rpcMapClients map[string]*rpc.Client
|
rpcMapClients map[string]*rpc.Client
|
||||||
port int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type rpcIdAddres struct {
|
type rpcIdAddres struct {
|
||||||
id string
|
id string
|
||||||
host string
|
host string
|
||||||
port int
|
index int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRpcClients(log *logger.Logger, mport int) *rpcClients {
|
func newRpcClients(conf *settings.RpcConfig) *rpcClientStub {
|
||||||
res := new(rpcClients)
|
res := new(rpcClientStub)
|
||||||
|
|
||||||
res.Logger = log
|
res.conf = conf
|
||||||
res.port = mport
|
|
||||||
|
|
||||||
res.rpcMapClients = make(map[string]*rpc.Client)
|
res.rpcMapClients = make(map[string]*rpc.Client)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rpcClients) flushRpcClients(ids []*rpcIdAddres) {
|
func (r *rpcClientStub) flushRpcClients(ids []*rpcIdAddres) {
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
defer r.mu.Unlock()
|
defer r.mu.Unlock()
|
||||||
|
|
||||||
@ -44,18 +43,22 @@ func (r *rpcClients) flushRpcClients(ids []*rpcIdAddres) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, idAddr := range ids {
|
for _, idAddr := range ids {
|
||||||
address := fmt.Sprintf("%s:%d", idAddr.host, r.port)
|
address := fmt.Sprintf("%s:%d", idAddr.host, idAddr.index+r.conf.BasePort)
|
||||||
|
|
||||||
cli, err := rpcsup.JsonClient(r.Logger, address)
|
cli, err := rpcsup.RpcClient(&rpcsup.RpcConfig{
|
||||||
|
Typec: r.conf.Type,
|
||||||
|
Network: r.conf.Network,
|
||||||
|
Address: address,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Sugar().Errorf("%s create rpc client error: %s", idAddr.id, address)
|
log.Sugar().Errorf("%s create rpc client error: %s", idAddr.id, address)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
r.rpcMapClients[idAddr.id] = cli
|
r.rpcMapClients[idAddr.id] = cli
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rpcClients) getConfig(id string, req models.UnisRpcRequest) (*models.UnisRpcResponse, error) {
|
func (r *rpcClientStub) getConfig(id string, req models.UnisRpcRequest) (*models.UnisRpcResponse, error) {
|
||||||
r.mu.RLock()
|
r.mu.RLock()
|
||||||
defer r.mu.RUnlock()
|
defer r.mu.RUnlock()
|
||||||
|
|
||||||
|
@ -1,54 +1,27 @@
|
|||||||
package uniss
|
package uniss
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"dashboard/logger"
|
|
||||||
"dashboard/models"
|
"dashboard/models"
|
||||||
"dashboard/pkg/rpcsup"
|
|
||||||
"dashboard/settings"
|
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type UnisRpcService struct {
|
// Alarm concurrency
|
||||||
*logger.Logger
|
type RpcServerStub struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRpcService(log *logger.Logger) *UnisRpcService {
|
func newrpcServerStub() *RpcServerStub {
|
||||||
res := new(UnisRpcService)
|
res := new(RpcServerStub)
|
||||||
|
|
||||||
res.Logger = log
|
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UnisRpcService) Config(res models.UnisRpcRequest, rsp *models.UnisRpcResponse) error {
|
// func (u *RpcServerStub) Name() string {
|
||||||
u.Sugar().Info("rpc server get mesage", res)
|
// return u.name
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (u *RpcServerStub) Config(res models.UnisRpcRequest, rsp *models.UnisRpcResponse) error {
|
||||||
|
log.Sugar().Info("rpc server get mesage", res)
|
||||||
|
|
||||||
rsp.Id = res.Id
|
rsp.Id = res.Id
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type unisRpcServer struct {
|
|
||||||
log *logger.Logger
|
|
||||||
port int
|
|
||||||
host string
|
|
||||||
typec string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newUnisRpcServer(log *logger.Logger, conf *settings.RpcConfig) *unisRpcServer {
|
|
||||||
res := new(unisRpcServer)
|
|
||||||
res.log = log
|
|
||||||
|
|
||||||
res.port = conf.Port
|
|
||||||
res.host = conf.Host
|
|
||||||
res.typec = conf.Type
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *unisRpcServer) rpcListenAndServe(ctx context.Context) error {
|
|
||||||
addrees := fmt.Sprintf("%s:%d", u.host, u.port)
|
|
||||||
|
|
||||||
return rpcsup.JsonServer(ctx, u.log, addrees, NewRpcService(u.log))
|
|
||||||
}
|
|
||||||
|
@ -36,13 +36,20 @@ type SqlConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UnisConfig struct {
|
type UnisConfig struct {
|
||||||
*RpcConfig `mapstructure:"rpc"`
|
Instances int `mapstructure:"instances"`
|
||||||
|
*RpcConfig `mapstructure:"rpc"`
|
||||||
|
*HttpClientConfig `mapstructure:"httpc"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RpcConfig struct {
|
type RpcConfig struct {
|
||||||
Port int `mapstructure:"port"`
|
BasePort int `mapstructure:"base_port"`
|
||||||
Host string `mapstructure:"host"`
|
Network string `mapstructure:"network"`
|
||||||
Type string `mapstructure:"type"`
|
Host string `mapstructure:"host"`
|
||||||
|
Type string `mapstructure:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HttpClientConfig struct {
|
||||||
|
Clients int `mapstructure:"clients"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SnowflakeConfig struct {
|
type SnowflakeConfig struct {
|
||||||
|
@ -10,3 +10,12 @@ func GetFuncName(fn interface{}) string {
|
|||||||
|
|
||||||
return runtime.FuncForPC(ptr).Name()
|
return runtime.FuncForPC(ptr).Name()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetInterfaceName(obj interface{}) string {
|
||||||
|
t := reflect.TypeOf(obj)
|
||||||
|
if t.Kind() == reflect.Ptr {
|
||||||
|
t = t.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.Name()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user