sync: 同步生产版 v1.0.4 并脱敏
This commit is contained in:
@@ -1,15 +1,80 @@
|
||||
package upstreamimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"fmt"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-upstream-proxy/internal/model"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"strings"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-upstream-proxy/internal/model"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/net/gclient"
|
||||
)
|
||||
|
||||
const (
|
||||
// gatewayBatchTimeoutConfigKey 限制单次批量转发的最长等待,防止上游异常时无限占用连接。
|
||||
gatewayBatchTimeoutConfigKey = "gateway.batchTimeout"
|
||||
// defaultGatewayBatchTimeout 覆盖 100 张卡按单卡 10 秒预算的最坏耗时,并留有余量。
|
||||
defaultGatewayBatchTimeout = 20 * time.Minute
|
||||
// defaultDataServiceTimeout 是数据开停转发的独立预算。
|
||||
defaultDataServiceTimeout = 210 * time.Second
|
||||
)
|
||||
|
||||
// configureGatewayTimeout 让响应头等待与整次请求使用同一预算,避免默认30秒提前中断。
|
||||
// upstream-chan 对批量操作按卡串行调用运营商接口,耗时随卡数线性增长;
|
||||
// 因此批量请求不能沿用 gclient 默认的 30 秒响应头超时,否则请求仍在办理就会被判为失败。
|
||||
func configureGatewayTimeout(ctx context.Context, client *gclient.Client, path string, count int, perCard time.Duration) {
|
||||
if path == "/sim/change/sim-apn" || path == "/sim/query/sim-apn-capability" {
|
||||
client.SetContentType("application/json")
|
||||
}
|
||||
applyGatewayTimeout(client, path, count, perCard,
|
||||
configDuration(ctx, "gateway.dataServiceTimeout", defaultDataServiceTimeout),
|
||||
configDuration(ctx, gatewayBatchTimeoutConfigKey, defaultGatewayBatchTimeout))
|
||||
}
|
||||
|
||||
// applyGatewayTimeout 计算并应用单次转发预算:整次请求与响应头等待必须一致,
|
||||
// 否则响应头超时会在业务仍在办理时提前中断请求。
|
||||
func applyGatewayTimeout(client *gclient.Client, path string, count int, perCard, dataServiceTimeout, batchTimeout time.Duration) {
|
||||
if count < 1 {
|
||||
count = 1
|
||||
}
|
||||
if perCard <= 0 {
|
||||
perCard = 10 * time.Second
|
||||
}
|
||||
timeout := perCard * time.Duration(count)
|
||||
if path == "/sim/change/sim-apn" {
|
||||
timeout = dataServiceTimeout
|
||||
if timeout <= 0 {
|
||||
timeout = defaultDataServiceTimeout
|
||||
}
|
||||
} else if batchTimeout > 0 && timeout > batchTimeout {
|
||||
timeout = batchTimeout
|
||||
}
|
||||
client.SetTimeout(timeout)
|
||||
if transport, ok := client.Transport.(*http.Transport); ok {
|
||||
transport.ResponseHeaderTimeout = timeout
|
||||
}
|
||||
}
|
||||
|
||||
// configDuration 读取时长配置,兼容写成 "20m" 字符串或秒数整数两种形式。
|
||||
func configDuration(ctx context.Context, key string, fallback time.Duration) time.Duration {
|
||||
value := g.Cfg().MustGet(ctx, key)
|
||||
if value == nil || value.IsNil() {
|
||||
return fallback
|
||||
}
|
||||
if duration := value.Duration(); duration >= time.Second {
|
||||
return duration
|
||||
}
|
||||
if seconds := value.Int(); seconds > 0 {
|
||||
return time.Duration(seconds) * time.Second
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func readGatewayResponse(response *gclient.Response) (model.SimBaseResJson, error) {
|
||||
defer response.Close()
|
||||
body := response.ReadAll()
|
||||
|
||||
Reference in New Issue
Block a user