dashboard/services/uniss/httpclienthandle.go
2025-06-04 17:07:17 +08:00

132 lines
2.9 KiB
Go

package uniss
import (
"bytes"
"dashboard/dao/sqldb"
"dashboard/models"
"dashboard/pkg/singlemap"
"dashboard/pkg/swarm"
"encoding/json"
"io"
"net/http"
"sync"
"time"
"go.uber.org/zap"
)
type httpClientHandler struct {
swarm *swarm.Swarm[*models.UnisHttpClientRequest]
httpC chan *models.UnisHttpClientRequest
client *http.Client
callMap *singlemap.SingleMap[uint64, models.UnisHttpClientHandlerFunc]
pool sync.Pool
sn uint64
}
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.UnisHttpClientRequest)
res.client = http.DefaultClient
res.callMap = singlemap.NewSingleMap[uint64, models.UnisHttpClientHandlerFunc]()
res.pool.New = func() any { return new(models.UnisHttpClientRequest) }
return res
}
func (c *httpClientHandler) getSn() uint64 {
c.sn++
return c.sn
}
// cald by mainthred
func (c *httpClientHandler) curl(method string, url string, body interface{}, handle models.UnisHttpClientHandlerFunc) {
req := c.pool.Get().(*models.UnisHttpClientRequest)
req.SetResParam(method, url, body, c.getSn(), handle)
if req.Handle != nil {
c.callMap.Put(req.Sn, req.Handle)
}
c.swarm.Submit(req)
}
// cald by mainthred
func (c *httpClientHandler) httpClientHandle(msg *models.UnisHttpClientRequest) {
defer func() {
c.pool.Put(msg)
c.callMap.Del(msg.Sn)
}()
if call, ok := c.callMap.Get(msg.Sn); ok && call != nil {
if err := call(msg); err != nil {
log.Sugar().Error(err)
return
}
log.Sugar().Infof("sn: %d, url: %s, handle ok", msg.Sn, msg.Url)
return
}
if err, ok := msg.Msg.(error); ok {
log.Sugar().Errorf("sn: %d, url: %s, no handle find and get err: %v", msg.Sn, msg.Url, err)
return
}
log.Sugar().Warnf("sn: %d, url: %s, no handle find body: %s", msg.Sn, msg.Url, string(msg.Msg.([]byte)))
}
// Note cald by swarm goroutines
func (c *httpClientHandler) doRequest(req *models.UnisHttpClientRequest) error {
defer func() {
c.httpC <- req
}()
body, err := json.Marshal(req.Msg)
if err != nil {
req.Msg = err
log.Sugar().Error(err)
return err
}
reqs, err := http.NewRequest(req.Methord, req.Url, bytes.NewReader(body))
if err != nil {
req.Msg = err
log.Sugar().Error(err)
return err
}
c.client.Timeout = time.Second
reqs.Header.Add("Content-type", "application/json;charset=utf-8")
reqs.Header.Add("User-Agent", "avcnetRuntime/0.0.1")
resp, err := c.client.Do(reqs)
if err != nil {
req.Msg = err
log.Sugar().Error(err)
return err
}
defer resp.Body.Close()
msg, err := io.ReadAll(resp.Body)
if err != nil {
req.Msg = err
log.Sugar().Error(err)
return err
}
if err := sqldb.ResFulDataStore(req.Methord, req.Url, string(body), string(msg), 0); err != nil {
req.Msg = err
log.Sugar().Error(err)
return err
}
req.Msg = msg
return nil
}