F13 动态客户端原先把 TEST_WEKNORA_HTTP_TIMEOUT(默认 60s)强制截成 10s, 与 readiness 探针上限混用,导致上传/轮询等业务请求 10s 即超时。 现在显式正超时原样传入;未配置/非正值回落到 appconfig 的 60s 默认。 readiness 探测自己的 10s 上限不变。 新增本地 httptest:60s 配置下 11s 响应成功,显式 50ms 短超时仍生效; 端点/凭据/绑定动态解析回归保持通过。make verify 17 项通过。
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## 开发快照 0.1.358(业务 HTTP 超时不再被探针上限截断)
|
||||
|
||||
### Fixed
|
||||
|
||||
- **F13 超时回归**:`weknoraaccess.Client` 不再把显式配置的
|
||||
`TEST_WEKNORA_HTTP_TIMEOUT`(默认 60s)强制截成 10s。只有未配置/非正值才回落到
|
||||
与原 appconfig 一致的 60s;readiness 探测自身的 10s 上限保持独立。11s 本地响应在
|
||||
60s 配置下可完成,显式 50ms 短超时仍生效。
|
||||
|
||||
## 开发快照 0.1.357(取件后自动解析、定位一次性请求、worker 有效配置)
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -11,6 +11,10 @@ import (
|
||||
|
||||
var ErrNotConfigured = errors.New("WeKnora 有效端点/凭据未配置")
|
||||
|
||||
// defaultBusinessTimeout matches appconfig's TEST_WEKNORA_HTTP_TIMEOUT default.
|
||||
// The readiness probe has its own 10s cap; it must not bound upload/poll calls.
|
||||
const defaultBusinessTimeout = 60 * time.Second
|
||||
|
||||
// Client resolves the effective WeKnora target on every call. It deliberately
|
||||
// owns no cached *weknora.Client: endpoint, key and binding are console-managed.
|
||||
type Client struct {
|
||||
@@ -28,8 +32,8 @@ func (client *Client) with(ctx context.Context, call func(*weknora.Client) error
|
||||
return ErrNotConfigured
|
||||
}
|
||||
timeout := client.Timeout
|
||||
if timeout <= 0 || timeout > 10*time.Second {
|
||||
timeout = 10 * time.Second
|
||||
if timeout <= 0 {
|
||||
timeout = defaultBusinessTimeout
|
||||
}
|
||||
remote, err := weknora.NewClient(weknora.ClientConfig{
|
||||
BaseURL: target.BaseURL,
|
||||
|
||||
@@ -51,3 +51,60 @@ func TestDynamicClientReResolvesEndpointKeyAndBinding(t *testing.T) {
|
||||
t.Fatalf("rotated endpoint/key = %#v, %v", knowledge, err)
|
||||
}
|
||||
}
|
||||
|
||||
// F13 timeout regression: the configured business timeout (default 60s) must
|
||||
// reach upload/poll clients unchanged; only a missing/zero value falls back.
|
||||
// The readiness probe's 10s cap must not leak into business HTTP.
|
||||
func TestConfiguredBusinessTimeoutIsNotCappedToProbeTimeout(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
select {
|
||||
case <-time.After(11 * time.Second):
|
||||
_, _ = w.Write([]byte(`{"success":true,"data":{"id":"slow-but-valid"}}`))
|
||||
case <-r.Context().Done():
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
client := &Client{
|
||||
Resolver: readiness.Resolver{
|
||||
Endpoint: func(context.Context) string { return server.URL },
|
||||
ReadKey: func() (string, error) { return "isolated-test-key", nil },
|
||||
DefaultKB: "isolated-test-kb",
|
||||
},
|
||||
Timeout: 60 * time.Second,
|
||||
}
|
||||
started := time.Now()
|
||||
item, err := client.GetKnowledge(context.Background(), "slow-but-valid")
|
||||
if err != nil {
|
||||
t.Fatalf("60s business timeout rejected 11s response after %s: %v", time.Since(started), err)
|
||||
}
|
||||
if item.ID != "slow-but-valid" {
|
||||
t.Fatalf("wrong response identity: %q", item.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// An explicit short timeout is still honoured for callers that need it.
|
||||
func TestExplicitShortBusinessTimeoutStillApplies(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
select {
|
||||
case <-time.After(300 * time.Millisecond):
|
||||
_, _ = w.Write([]byte(`{"success":true,"data":{"id":"too-late"}}`))
|
||||
case <-r.Context().Done():
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
client := &Client{
|
||||
Resolver: readiness.Resolver{
|
||||
Endpoint: func(context.Context) string { return server.URL },
|
||||
ReadKey: func() (string, error) { return "isolated-test-key", nil },
|
||||
DefaultKB: "isolated-test-kb",
|
||||
},
|
||||
Timeout: 50 * time.Millisecond,
|
||||
}
|
||||
started := time.Now()
|
||||
if _, err := client.GetKnowledge(context.Background(), "too-late"); err == nil {
|
||||
t.Fatal("explicit 50ms timeout did not bound the call")
|
||||
}
|
||||
if elapsed := time.Since(started); elapsed > 2*time.Second {
|
||||
t.Fatalf("explicit short timeout took %s", elapsed)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user