规划mesh请求的框架结构, 细节待完善
This commit is contained in:
@ -6,3 +6,109 @@
|
||||
//
|
||||
// Date : 2025-03-28 14:11
|
||||
package mesh
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.zhangdeman.cn/zhangdeman/network/httpclient"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func Request(req *RequestConfig, receiver any) *Response {
|
||||
if nil == req.Ctx {
|
||||
req.Ctx = context.Background()
|
||||
}
|
||||
c := &client{
|
||||
resp: &Response{
|
||||
IsSuccess: false,
|
||||
ErrorCode: "",
|
||||
ErrorMessage: "",
|
||||
Raw: nil,
|
||||
DataMap: nil,
|
||||
AliasResultTable: make(map[string]*Response),
|
||||
Lock: &sync.RWMutex{},
|
||||
},
|
||||
reqCfg: req,
|
||||
receiver: receiver,
|
||||
}
|
||||
return c.Request()
|
||||
}
|
||||
|
||||
type client struct {
|
||||
ctx context.Context
|
||||
resp *Response
|
||||
reqCfg *RequestConfig
|
||||
receiver any
|
||||
}
|
||||
|
||||
func (c *client) Request() *Response {
|
||||
for _, itemGroup := range c.reqCfg.Group {
|
||||
if !c.doRequest(itemGroup) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return c.resp
|
||||
}
|
||||
|
||||
// doRequest 返回是否继续
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:30 2025/3/28
|
||||
func (c *client) doRequest(apiList []*RequestConfigGroupItem) bool {
|
||||
if len(apiList) == 0 {
|
||||
return true
|
||||
}
|
||||
// 初始化请求配置, 并获取 http client 实例
|
||||
httpClientList := make([]*httpclient.HttpClient, 0)
|
||||
for _, apiCfg := range apiList {
|
||||
var (
|
||||
err error
|
||||
httpClient *httpclient.HttpClient
|
||||
)
|
||||
// 初始化一下请求
|
||||
c.initApiCfg(apiCfg)
|
||||
if httpClient, err = httpclient.NewHttpClient(apiCfg.RequestCfg, apiCfg.CacheInstance); nil != err {
|
||||
// 此处获取客户端实例即发生异常, 忽略一切配置, 直接作为全局失败, 后续也不请求了
|
||||
c.resp.ErrorCode = "-500"
|
||||
c.resp.ErrorMessage = err.Error()
|
||||
return false
|
||||
}
|
||||
httpClientList = append(httpClientList, httpClient)
|
||||
}
|
||||
isContinue := true
|
||||
wg := &sync.WaitGroup{}
|
||||
for idx, apiCfg := range apiList {
|
||||
wg.Add(1)
|
||||
go func(clientIdx int, apiCfg *RequestConfigGroupItem) {
|
||||
defer func() {
|
||||
if err := recover(); nil != err {
|
||||
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
// TODO : 判断是否已经是最终失败
|
||||
resp := httpClientList[clientIdx].Request()
|
||||
c.resp.Lock.Lock()
|
||||
defer c.resp.Lock.Unlock()
|
||||
if !resp.IsSuccess {
|
||||
}
|
||||
}(idx, apiCfg)
|
||||
}
|
||||
wg.Wait()
|
||||
return isContinue
|
||||
}
|
||||
|
||||
func (c *client) initApiCfg(apiCfg *RequestConfigGroupItem) {
|
||||
if apiCfg.FailBehavior == nil {
|
||||
apiCfg.FailBehavior = &RequestConfigGroupItemFailBehavior{
|
||||
Action: FailBehaviorError, // 默认失败终止请求
|
||||
FinalFailure: true, // 默认一旦失败,则争个整个失败
|
||||
}
|
||||
}
|
||||
if apiCfg.FailBehavior.Action == FailBehaviorError {
|
||||
// 配置了请求失败则报错, 一定是导致结果最终失败
|
||||
apiCfg.FailBehavior.FinalFailure = true
|
||||
}
|
||||
// 每一个请求有独立的context
|
||||
apiCfg.RequestCfg.Ctx = context.WithValue(c.reqCfg.Ctx, "alias", apiCfg.Alias)
|
||||
}
|
||||
|
Reference in New Issue
Block a user