1 回答
TA贡献1752条经验 获得超4个赞
永远不要使用time.Sleep,特别是如果它是一个很长的时期 - 因为它是不间断的。为什么这很重要?如果它在一个 goroutine 中并且该任务不会完成(即上下文被取消),那么您宁愿立即中止。
因此,要创建一个带有取消的轮询等待:
select {
case <-ctx.Done(): // cancel early if context is canceled
return ctx.Err()
case <-time.After(pollInterval): // wait for pollInterval duration
}
将较大的超时时间放在输入上下文中:
ctx := context.TODO() // <- outer request context goes here or context.Background()
// wrap context with a timeout
ctx, cancel := context.WithTimeout(ctx, 1 * time.Minute)
defer cancel() // avoid leaks
err := c.WaitForServiceToComeAlive(ctx, "job", 10*time.Second /* poll interval */)
然后您的服务等待功能简化为:
func (c *Client) WaitForServiceToComeAlive(ctx context.Context, name string, pollInterval time.Duration) error {
var mysvc *Service
var err error
for {
mysvc, err = c.GetService(name) // <- this should take a ctx too - if possible for early cancelation
if err != nil {
return err
}
if mysvc != nil {
return nil
}
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(pollInterval):
}
}
}
https://play.golang.org/p/JwH5CMyY0I2
- 1 回答
- 0 关注
- 71 浏览
添加回答
举报