|
@@ -9,6 +9,9 @@ import (
|
|
|
"github.com/spf13/cast"
|
|
|
"github.com/spf13/viper"
|
|
|
"strconv"
|
|
|
+ "sync"
|
|
|
+
|
|
|
+ "github.com/sourcegraph/conc"
|
|
|
)
|
|
|
|
|
|
type GlobalLimitService interface {
|
|
@@ -119,37 +122,95 @@ func (s *globalLimitService) AddGlobalLimit(ctx context.Context, req v1.GlobalLi
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- tcpLimitRuleId, err := s.tcpLimit.AddTcpLimit(ctx, &v1.GeneralLimitRequireRequest{
|
|
|
- Tag: require.GlobalLimitName,
|
|
|
- HostId: req.HostId,
|
|
|
- RuleId: ruleId,
|
|
|
- Uid: req.Uid,
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
+ // 使用conc库并发执行API调用
|
|
|
+ var tcpLimitRuleId, udpLimitRuleId, webLimitRuleId, gateWayGroupId int
|
|
|
+ var mu sync.Mutex // 用于保护共享变量
|
|
|
+
|
|
|
+ // 为每个并发调用创建独立的请求参数(深拷贝)
|
|
|
+ // 避免共享同一个指针可能导致的数据竞争
|
|
|
+
|
|
|
+ // 创建网关组请求参数
|
|
|
+ gateWayReq := v1.AddGateWayGroupRequest{
|
|
|
+ Name: require.GlobalLimitName,
|
|
|
+ Comment: req.Comment,
|
|
|
}
|
|
|
- udpLimitRuleId, err := s.udpLimit.AddUdpLimit(ctx, &v1.GeneralLimitRequireRequest{
|
|
|
- Tag: require.GlobalLimitName,
|
|
|
- HostId: req.HostId,
|
|
|
- RuleId: ruleId,
|
|
|
- Uid: req.Uid,
|
|
|
+
|
|
|
+ // 创建一个WaitGroup来协调多个并发任务
|
|
|
+ wg := conc.NewWaitGroup()
|
|
|
+
|
|
|
+ // 启动tcpLimit调用 - 使用独立的请求参数副本
|
|
|
+ wg.Go(func() {
|
|
|
+ // 为该goroutine创建独立的请求参数副本
|
|
|
+ tcpLimitReq := &v1.GeneralLimitRequireRequest{
|
|
|
+ Tag: require.GlobalLimitName,
|
|
|
+ HostId: req.HostId,
|
|
|
+ RuleId: ruleId,
|
|
|
+ Uid: req.Uid,
|
|
|
+ }
|
|
|
+ result, e := s.tcpLimit.AddTcpLimit(ctx, tcpLimitReq)
|
|
|
+ mu.Lock()
|
|
|
+ if e != nil {
|
|
|
+ err = e
|
|
|
+ } else {
|
|
|
+ tcpLimitRuleId = result
|
|
|
+ }
|
|
|
+ mu.Unlock()
|
|
|
})
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- webLimitRuleId, err := s.webLimit.AddWebLimit(ctx, &v1.GeneralLimitRequireRequest{
|
|
|
- Tag: require.GlobalLimitName,
|
|
|
- HostId: req.HostId,
|
|
|
- RuleId: ruleId,
|
|
|
- Uid: req.Uid,
|
|
|
+
|
|
|
+ // 启动udpLimit调用 - 使用独立的请求参数副本
|
|
|
+ wg.Go(func() {
|
|
|
+ // 为该goroutine创建独立的请求参数副本
|
|
|
+ udpLimitReq := &v1.GeneralLimitRequireRequest{
|
|
|
+ Tag: require.GlobalLimitName,
|
|
|
+ HostId: req.HostId,
|
|
|
+ RuleId: ruleId,
|
|
|
+ Uid: req.Uid,
|
|
|
+ }
|
|
|
+ result, e := s.udpLimit.AddUdpLimit(ctx, udpLimitReq)
|
|
|
+ mu.Lock()
|
|
|
+ if e != nil {
|
|
|
+ err = e
|
|
|
+ } else {
|
|
|
+ udpLimitRuleId = result
|
|
|
+ }
|
|
|
+ mu.Unlock()
|
|
|
})
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- gateWayGroupId, err := s.gateWayGroup.AddGatewayGroup(ctx, v1.AddGateWayGroupRequest{
|
|
|
- Name: require.GlobalLimitName,
|
|
|
- Comment: req.Comment,
|
|
|
+
|
|
|
+ // 启动webLimit调用 - 使用独立的请求参数副本
|
|
|
+ wg.Go(func() {
|
|
|
+ // 为该goroutine创建独立的请求参数副本
|
|
|
+ webLimitReq := &v1.GeneralLimitRequireRequest{
|
|
|
+ Tag: require.GlobalLimitName,
|
|
|
+ HostId: req.HostId,
|
|
|
+ RuleId: ruleId,
|
|
|
+ Uid: req.Uid,
|
|
|
+ }
|
|
|
+ result, e := s.webLimit.AddWebLimit(ctx, webLimitReq)
|
|
|
+ mu.Lock()
|
|
|
+ if e != nil {
|
|
|
+ err = e
|
|
|
+ } else {
|
|
|
+ webLimitRuleId = result
|
|
|
+ }
|
|
|
+ mu.Unlock()
|
|
|
})
|
|
|
+
|
|
|
+ // 启动gatewayGroup调用
|
|
|
+ wg.Go(func() {
|
|
|
+ result, e := s.gateWayGroup.AddGatewayGroup(ctx, gateWayReq)
|
|
|
+ mu.Lock()
|
|
|
+ if e != nil {
|
|
|
+ err = e
|
|
|
+ } else {
|
|
|
+ gateWayGroupId = result
|
|
|
+ }
|
|
|
+ mu.Unlock()
|
|
|
+ })
|
|
|
+
|
|
|
+ // 等待所有调用完成
|
|
|
+ wg.Wait()
|
|
|
+
|
|
|
+ // 检查是否有错误发生
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|