fix(agent): 读上限要容得下整批轮询结果
同一类缺陷的第四处,也是最难发现的一处,因为它在最繁忙那条接缝的另一侧。agent 限制自己从中继读多少,而那个上限必须容得下中继**合法能发**的最大东西:一整批 轮询结果,即每个邮箱槽一个信封。原值 1 MiB 是"给宽一点"拍出来的,没有任何推导; 而按策略上限算,满邮箱的一批约 4 MiB。于是 agent 会拒掉一个中继答得好好的轮询, 然后重试进同一个拒绝——表现为持续的连接抖动,日志说"relay response exceeds 1048576 bytes",而中继那边一切正常。 现在取 8 MiB,并把推导写清楚:中继信封上限 × 邮箱深度,留一档余量。两侧的关系由 test/limits.test.js 钉住(常量从 Go 源码读出),因为这是跨语言、跨进程的一对数字, 任何一侧单独都看不到。 变异验证:改回 1 MiB,测试失败。 Node 119 项、Go 全包、Swift 101 项通过。
This commit is contained in:
@@ -35,6 +35,21 @@ const (
|
||||
PathDevices = "/v1/agent/devices"
|
||||
)
|
||||
|
||||
// DefaultMaxBytes bounds a relay response body.
|
||||
//
|
||||
// It has to admit a full long-poll batch, which is the largest thing the relay can legitimately send:
|
||||
// one envelope per mailbox slot. The previous 1 MiB was chosen as "generous" without being derived
|
||||
// from anything, and it is smaller than what the relay is now allowed to send — a mailbox of eight
|
||||
// envelopes at the policy's ceiling is about 4 MiB, so a full batch would have been refused as
|
||||
// "relay response exceeds 1048576 bytes", and the agent would have retried a poll the relay answered
|
||||
// correctly. That is the same class of defect as the relay's own envelope ceiling: a bound picked by
|
||||
// feel, on the other side of a seam, disagreeing with the party that produces the data.
|
||||
//
|
||||
// The derivation is stated here rather than computed from the policy because the agent reads the
|
||||
// policy for its own limits; the two numbers are pinned against each other by
|
||||
// test/limits.test.js, which is where a change on either side becomes visible.
|
||||
const DefaultMaxBytes int64 = 8 << 20
|
||||
|
||||
var (
|
||||
// ErrSessionExpired means the relay no longer recognises this session. The caller re-runs the
|
||||
// handshake and polls again; it is not an error worth crashing over.
|
||||
@@ -142,7 +157,7 @@ func New(cfg Config) (*Client, error) {
|
||||
}
|
||||
maxBytes := cfg.MaxBytes
|
||||
if maxBytes <= 0 {
|
||||
maxBytes = 1 << 20
|
||||
maxBytes = DefaultMaxBytes
|
||||
}
|
||||
client := &http.Client{Timeout: timeout}
|
||||
if cfg.RootCAs != nil {
|
||||
|
||||
Reference in New Issue
Block a user