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 }