mirror of
https://github.com/hanzoai/tasks.git
synced 2026-10-04 02:04:03 +00:00
## What changed? Added a "soft timeout" (language used by Workflow Update) to `GetWorkflowExecutionHistory` long polls. ## Why? We don't want to terminate the long poll connection but instead keep it alive by sending a response back just before the timeout. The idea is that this will prevent connections from opening/terminating repeatedly (ie connection churn). ## How did you test it? - [ ] built - [x] run locally and tested manually - [x] covered by existing tests - [ ] added new unit test(s) - [ ] added new functional test(s) ## Potential risks I was only able to verify this manually by forcing a timeout in the server and verifying that instead of a deadline exceeded I saw a result. I'll assume this will work since the existing code already tried doing just exactly that, but it didn't do it well.
38 lines
952 B
Go
38 lines
952 B
Go
package contextutil
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
var noop = func() {}
|
|
|
|
// WithDeadlineBuffer creates a child context with desired timeout.
|
|
// If buffer is non-zero, then child context timeout will be
|
|
// the minOf(parentCtx.Deadline()-buffer, maxTimeout). Use this
|
|
// method to create child context when childContext cannot use
|
|
// all of parent's deadline but instead there is a need to leave
|
|
// some time for parent to do some post-work
|
|
func WithDeadlineBuffer(
|
|
parent context.Context,
|
|
timeout time.Duration,
|
|
buffer time.Duration,
|
|
) (context.Context, context.CancelFunc) {
|
|
if parent.Err() != nil {
|
|
return parent, noop
|
|
}
|
|
|
|
deadline, hasDeadline := parent.Deadline()
|
|
|
|
if !hasDeadline {
|
|
return context.WithTimeout(parent, timeout)
|
|
}
|
|
|
|
remaining := time.Until(deadline) - buffer
|
|
if remaining < timeout {
|
|
// Cap the timeout to the remaining time minus buffer.
|
|
timeout = max(0, remaining)
|
|
}
|
|
return context.WithTimeout(parent, timeout)
|
|
}
|