go/protocol/internal/timeout.go (57 lines of code) (raw):
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
package internal
import (
"context"
"fmt"
"math"
"time"
"github.com/Azure/iot-operations-sdks/go/internal/wallclock"
"github.com/Azure/iot-operations-sdks/go/protocol/errors"
)
// Struct to apply an optional timeout.
type Timeout struct {
time.Duration
Name string
Text string
}
func (to *Timeout) Validate() error {
switch {
case to.Duration < 0:
return &errors.Client{
Message: "timeout cannot be negative",
Kind: errors.ConfigurationInvalid{
PropertyName: "Timeout",
PropertyValue: to,
},
}
case to.Seconds() > math.MaxUint32:
return &errors.Client{
Message: "timeout too large",
Kind: errors.ConfigurationInvalid{
PropertyName: "Timeout",
PropertyValue: to,
},
}
default:
return nil
}
}
func (to *Timeout) Context(
ctx context.Context,
) (context.Context, context.CancelFunc) {
if to.Duration == 0 {
return context.WithCancel(ctx)
}
return wallclock.Instance.WithTimeoutCause(
ctx,
to.Duration,
&errors.Client{
Message: fmt.Sprintf("%s timed out", to.Text),
Kind: errors.Timeout{
TimeoutName: to.Name,
TimeoutValue: to.Duration,
},
},
)
}
func (to *Timeout) MessageExpiry() uint32 {
return uint32(math.Ceil(to.Seconds()))
}