feat: 添加 WithDefaultTimeout 默认超时配置
Invoke 之前完全依赖调用方传入的 ctx 控制超时,池子被占满或 Python 侧 handler 阻塞时,未设置 deadline 的调用会永久阻塞且不报错。新增 WithDefaultTimeout 选项,仅在 ctx 未设置 deadline 时兜底生效,调用方 显式设置的超时优先级更高。 同时补充 example 中的阻塞/超时演示(demoTimeout、demoBlocking)和 pool_test.go 集成测试,覆盖池占满排队、默认超时、显式 deadline 优先级、 流式输出超时后 channel 静默关闭等场景。
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"reflect"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
// poolConfig 是进程池内部配置,通过 Option 函数填充
|
||||
@@ -23,6 +24,7 @@ type poolConfig struct {
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
handler any
|
||||
defaultTimeout time.Duration
|
||||
}
|
||||
|
||||
// Option 是 NewPool 的函数选项
|
||||
@@ -74,6 +76,14 @@ func WithStderr(w io.Writer) Option {
|
||||
return func(c *poolConfig) { c.stderr = w }
|
||||
}
|
||||
|
||||
// WithDefaultTimeout 设置 Invoke 调用的默认超时时间(默认不启用)。
|
||||
// 仅当调用方传入的 ctx 未设置 deadline 时才会生效,用于防止调用方忘记设置超时导致
|
||||
// Invoke 无限期阻塞(例如所有 worker 连接被占满,或 Python 侧 handler 阻塞不返回)。
|
||||
// 调用方通过 context.WithTimeout 显式设置的超时优先级更高,不会被覆盖。
|
||||
func WithDefaultTimeout(d time.Duration) Option {
|
||||
return func(c *poolConfig) { c.defaultTimeout = d }
|
||||
}
|
||||
|
||||
// WithHandlers 注册 Go handler struct,其所有公开方法自动暴露给 Python 通过 call_go() 调用。
|
||||
//
|
||||
// type MyService struct{}
|
||||
@@ -93,6 +103,7 @@ type Pool interface {
|
||||
acquire(ctx context.Context) (net.Conn, *worker, error)
|
||||
nextReqID() uint64
|
||||
callbackDispatch(ctx context.Context, msg Message) (any, string)
|
||||
defaultTimeout() time.Duration
|
||||
}
|
||||
|
||||
// ── goHandler ────────────────────────────────────────────────────────────────
|
||||
@@ -105,15 +116,15 @@ type goHandler struct {
|
||||
hasErr bool
|
||||
}
|
||||
|
||||
|
||||
// ── pool(内部实现)─────────────────────────────────────────────────────────
|
||||
|
||||
type pool struct {
|
||||
workers []*worker
|
||||
idx atomic.Uint64
|
||||
reqID atomic.Uint64
|
||||
mu sync.RWMutex
|
||||
handlers map[string]goHandler
|
||||
workers []*worker
|
||||
idx atomic.Uint64
|
||||
reqID atomic.Uint64
|
||||
mu sync.RWMutex
|
||||
handlers map[string]goHandler
|
||||
defTimeout time.Duration
|
||||
}
|
||||
|
||||
// NewPool 创建并启动进程池。
|
||||
@@ -151,7 +162,7 @@ func NewPool(script string, opts ...Option) (Pool, error) {
|
||||
workers[i] = w
|
||||
}
|
||||
|
||||
p := &pool{workers: workers, handlers: make(map[string]goHandler)}
|
||||
p := &pool{workers: workers, handlers: make(map[string]goHandler), defTimeout: cfg.defaultTimeout}
|
||||
|
||||
if cfg.handler != nil {
|
||||
p.bindHandlers(cfg.handler)
|
||||
@@ -231,6 +242,10 @@ func (p *pool) nextReqID() uint64 {
|
||||
return p.reqID.Add(1)
|
||||
}
|
||||
|
||||
func (p *pool) defaultTimeout() time.Duration {
|
||||
return p.defTimeout
|
||||
}
|
||||
|
||||
func (p *pool) callbackDispatch(ctx context.Context, msg Message) (any, string) {
|
||||
p.mu.RLock()
|
||||
h, ok := p.handlers[msg.Method]
|
||||
|
||||
Reference in New Issue
Block a user