Home > Blockchain >  How to detect a timeout occurred using Go's WithTimeout
How to detect a timeout occurred using Go's WithTimeout

Time:01-27

I have the following Go code:

func MyFunc(ctx context.Context, cfg *Config) (packedevent []byte, err error, publishEvent bool) {
    var cancel context.CancelFunc
    ctx, cancel = context.WithTimeout(ctx, cfg.ScanTimeout)
    defer cancel()

    event := GetEvent(ctx, cfg)
    packedevent, err = PackEvent(event)

    publishEvent = shouldSendToIoT(event)

    return
}

I am trying to cause this function to timeout using context.WithTimeout.

What I have not been able to figure out is how to set err if the timeout occurs.

I looked at the example in the Go docs but I did not really understand it. Does the <-ctx.Done() case always mean that the timeout was reached? This example seems to suggest the opposite - that <-ctx.Done() means the code ran to completion without timing out.

I am looking for clarification on how to detect when code run with context.WithTimeout has or has not timed out.

Additionally, I would like to understand where in my code I should check if the timeout occurred. My first thought was to put this check at the end of the function, but would that be putting the check too late?

CodePudding user response:

To detect if the context has timed out, check ctx.Error(). If the error is context.Canceled, then the context has been canceled using the cancel() function. If it is context.DeadlineExceeded, then it timed out.

To check if the context has been canceled or timed out, use:

select {
   case <-ctx.Done():
       // canceled or timed out
   default:
       // So the select will not block
}

CodePudding user response:

ctx.Done() fires when the timeout is reached or the cancel func is called.

Per the docs:

Done returns a channel that's closed when work done on behalf of this context should be canceled.

  • Related