You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This might be a stretch for this library, but it would be cool if we had support for contexts, whether directly in this package or a sub-package like qzcontext.
Now, rather than doing context.WithTimeout you'd do clock.Context.WithTimeout(ctx, duration, "tag") (likewise for deadline) and be able to control expiry by advancing the clock.
Oh, that's an interesting thought. Off the top of my head
Discard timeouts not originating from quartz and print warning
Error, because the context timeout did not originate from quartz (limits usability, but maybe still useful within services)
Start watching the context that was passed into quartz context and track how long until it was cancelled -> measure against quartz elapsed time and if less, keep the quartz context active, otherwise cancel it.
For option 3, I imagine something like:
funcquartzContext(clock*quartz.Clock, parentCtx context.Context) context.Context {
detachedCtx, detachedCancelCause:=context.WithCancelCause(context.WithoutCancel(parentCtx))
startTime:=time.Now()
gofunc() {
<-parentCtx.Done()
duration:=time.Since(startTime)
parentErr:=parentCtx.Err()
// if clock advance > duration// detachedCancelCause(parentErr)//// else track advancement and cancel eventually
}()
returndetachedCtx
}
Edit: Oh yeah, forgot about ctx.Deadline() which could also be analyzed rather than the above timing. The context.WithoutCancel would still be useful.
FWIW #30 takes a fourth option, rather than trying to be clever, it allows real-clock timeouts to cancel quartz contexts early. Thanks to context.AfterFunc, the propagation is made very simple with no added goroutines.
In coder/coder, a common use-case we have is:
ctx:=testutil.Context(t, 30*time.Second)
That's the upper bound we want the test to run for. Given that quartz does not interfere with the deadline, tests will properly time out rather than waiting indefinitely if quartz clock isn't being advanced.
The user can still use context.WithoutCancel or similar in places where they want quartz to have full management.
If you wanted to control context timeouts for e.g. http handlers, you could:
Activity
spikecurtis commentedon May 22, 2025
IIRC, the reason I have been gunshy is how to deal with contexts that already have deadlines based on a real clock being passed into the mock clock.
mafredri commentedon May 22, 2025
Oh, that's an interesting thought. Off the top of my head
For option 3, I imagine something like:
Edit: Oh yeah, forgot about
ctx.Deadline()which could also be analyzed rather than the above timing. Thecontext.WithoutCancelwould still be useful.feat!: add Clock-backed context support
feat!: add Clock-backed context support
feat!: add Clock-backed context support
mafredri commentedon May 8, 2026
FWIW #30 takes a fourth option, rather than trying to be clever, it allows real-clock timeouts to cancel quartz contexts early. Thanks to
context.AfterFunc, the propagation is made very simple with no added goroutines.In coder/coder, a common use-case we have is:
That's the upper bound we want the test to run for. Given that quartz does not interfere with the deadline, tests will properly time out rather than waiting indefinitely if quartz clock isn't being advanced.
The user can still use
context.WithoutCancelor similar in places where they want quartz to have full management.If you wanted to control context timeouts for e.g. http handlers, you could:
Giving you the ability to clock.Advance and test the handler properly.