Go - 实现超时的最佳方式

我有一个异步部署的服务,我需要等待指定的时间才能使其上线。如果指定的时间过去了,我们仍然无法找到服务,那么我们就会出错。在 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

}


DIEA
浏览 56回答 1
1回答

温温酱

永远不要使用time.Sleep,特别是如果它是一个很长的时期 - 因为它是不间断的。为什么这很重要?如果它在一个 goroutine 中并且该任务不会完成(即上下文被取消),那么您宁愿立即中止。因此,要创建一个带有取消的轮询等待:select {case <-ctx.Done():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// cancel early if context is canceled&nbsp; &nbsp; 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 timeoutctx, cancel := context.WithTimeout(ctx, 1 * time.Minute)defer cancel() // avoid leakserr := c.WaitForServiceToComeAlive(ctx, "job", 10*time.Second /* poll interval */)然后您的服务等待功能简化为:func (c *Client) WaitForServiceToComeAlive(ctx context.Context, name string, pollInterval time.Duration) error {&nbsp; &nbsp; var mysvc *Service&nbsp; &nbsp; var err error&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; mysvc, err = c.GetService(name) // <- this should take a ctx too - if possible for early cancelation&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return err&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if mysvc != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return nil&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-ctx.Done():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ctx.Err()&nbsp; &nbsp; &nbsp; &nbsp; case <-time.After(pollInterval):&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}https://play.golang.org/p/JwH5CMyY0I2
打开App,查看更多内容
随时随地看视频慕课网APP