Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: runtime: add WaitIdle function #65336

Open
gh2o opened this issue Jan 29, 2024 · 4 comments
Open

proposal: runtime: add WaitIdle function #65336

gh2o opened this issue Jan 29, 2024 · 4 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Proposal
Milestone

Comments

@gh2o
Copy link

gh2o commented Jan 29, 2024

Proposal Details

I propose adding a new function WaitIdle to runtime.

The function will have the following function signature:

func WaitIdle() <-chan struct{}

WaitIdle will return a channel that will be closed at the next moment that no goroutines are runnable, i.e. all P's are idle.

The main use case of the WaitIdle function is for tests, where a user or library may need to wait for all downstream effects of a given wakeup to complete before proceeding with the test case.

Implementation of proposal here.

@gh2o gh2o added the Proposal label Jan 29, 2024
@gopherbot gopherbot added this to the Proposal milestone Jan 29, 2024
@mauri870 mauri870 added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jan 29, 2024
@bcmills
Copy link
Contributor

bcmills commented Jan 29, 2024

For reference, there is currently a similar function (but with a narrower scope) in the main repo:
https://cs.opensource.google/go/go/+/master:src/runtime/pprof/pprof_test.go;l=1023-1026;drc=9cdcb01320d9a866e46a2daedb9bde16e0d51278.

This also demonstrates that it is currently possible to implement this function as a third-party library, albeit a somewhat fragile one — it depends on the exact format of runtime.Stack goroutine dumps.

@seankhliao
Copy link
Member

would this be the same as #44026 ?

@gh2o
Copy link
Author

gh2o commented Jan 29, 2024

@bcmills I'm currently using a similar implementation, but created this proposal to see if there is interest in adding first-class support for it to the runtime, seeing that it could be a common use case.

@seankhliao This is different from a deadlock detector, which detects the case where all goroutines are in the waiting state, there are no active timers or netpoll sockets, and really only works when cgo is disabled. This only considers the case where all goroutines are in the waiting state, which can be useful for multiple real-world uses:

  • For tests, advancing mock time once all timers have fired
  • For tests, ensuring that there are no spinning / busy-looping background goroutines after ending the test case
  • Running idle work when the runtime has quiesced and there are spare CPU cycles

@gh2o
Copy link
Author

gh2o commented Mar 6, 2024

This proposal was mostly inspired by the this function in the Rust Tokio library, which implements a feature that I found immensely helpful for writing deterministic unit tests: it waits until the runtime has no work to do, then auto-advances the simulated runtime timer to the the next wakeup time.

Adding WaitIdle as proposed would allow for reliably implementing this feature for mock time implementations. Test code that purely utilizes the mock time implementation without touching time.* functions would be able to run deterministically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Proposal
Projects
Status: No status
Status: Incoming
Development

No branches or pull requests

5 participants