我有一個異步部署的服務,我需要等待指定的時間才能上線。如果指定的時間段過去了,我們仍然無法找到該服務,那么我們就會出錯。在 go 中撰寫此代碼的最佳方式是什么?我正在考慮使用context.WithTimeout但不確定這將如何作業。謝謝您的幫助!
func (c *Client) WaitForServiceToComeAlive(ctx context.Context, name string, timeout time.Duration) error {
var mysvc *Service
var err error
endtime := time.Now().Add(timeout)
for time.Now().Before(endtime) {
mysvc, err = c.GetService(ctx, name)
if err != nil {
return err
}
if mysvc != nil {
break
}
time.Sleep(time.Second * 10)
}
if mysvc == nil {
return fmt.Errorf("svc %s did not register", name)
}
return nil
}
uj5u.com熱心網友回復:
切勿使用,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
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/360679.html
上一篇:Vue順序執行
下一篇:如何停止異步回圈
