Simplifies context cancellation handling by using context.AfterFunc instead of a
goroutine to wait for context cancellation. This approach avoids the overhead of
a goroutine during the waiting period.
For ctxQuitUnsafe, since g.quit is closed only in the Quit method (which also
cancels all associated contexts), waiting on context cancellation ensures the
same behavior without unnecessary dependency on g.quit.
Added a test to ensure that the Create method does not launch any goroutines.
Removed 'cancel' argument, because it is called only in case the context has
already expired and the only action that cancel function did was cancelling the
context.
In this commit, the ContextGuard struct is re-worked such that the
context that its new main WithCtx method provides is cancelled in sync
with a parent context being cancelled or with it's quit channel being
cancelled. Tests are added to assert the behaviour. In order for the
close of the quit channel to be consistent with the cancelling of the
derived context, the quit channel _must_ be contained internal to the
ContextGuard so that callers are only able to close the channel via the
exposed Quit method which will then take care to first cancel any
derived context that depend on the quit channel before returning.
This adds the ContextGuard struct from the taproot-assets repository
that has been in use there for a while.
The context guard allows for easy creation of contexts that depend on a
central wait group and quit channel.
A context can either be created with a timeout and quit, meaning it will
cancel either on reaching the timeout or when the central quit channel
is closed.
Or a context can be created to block and use a timeout, meaning it will
_not_ cancel on quit but rather block the shutdown until it is completed
(or times out).
The third way is to create a context that just cancels on quit with no
timeout.