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

time: example of After includes a bad practice #43009

Closed
snadrus opened this issue Dec 4, 2020 · 10 comments
Closed

time: example of After includes a bad practice #43009

snadrus opened this issue Dec 4, 2020 · 10 comments
Labels
Documentation FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@snadrus
Copy link

snadrus commented Dec 4, 2020

Does this issue reproduce with the latest release? Yes

What operating system? All

What did you do?

Used the time.After example in production, specifically:
case <-time.Now().After(5*time.Minute):

What did you expect to see?

A sensible scaling of the example as load increased.

What did you see instead?

https://medium.com/@oboturov/golang-time-after-is-not-garbage-collected-4cbc94740082
Using this in a switch clause fails to account for the lack of on-demand garbage collection (documented) which (at scale) becomes a problem consuming GB of memory and causing GC churn.

@cagedmantis cagedmantis changed the title time.After example includes a bad practice time: example of After includes a bad practice Dec 4, 2020
@cagedmantis cagedmantis added Documentation NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Dec 4, 2020
@cagedmantis cagedmantis added this to the Backlog milestone Dec 4, 2020
@cagedmantis
Copy link
Contributor

/cc @rsc

@ianlancetaylor
Copy link
Contributor

@snadrus What do you recommend instead?

The GC behavior is clearly documented, and the alternative involves not using time.After at all. But still seems useful to have an example for time.After.

@snadrus
Copy link
Author

snadrus commented Dec 5, 2020

The risk is with "select" statements. Adding that to the documentation could help.

An example could have goroutine blocking: https://play.golang.org/p/0eUOnvITpcg

@cespare
Copy link
Contributor

cespare commented Dec 5, 2020

@snadrus your example would be better written with time.Sleep.

@snadrus
Copy link
Author

snadrus commented Dec 5, 2020 via email

@ianlancetaylor
Copy link
Contributor

There are many safe uses of time.After. And most such uses will be in select statements.

It's true that if you have many calls to select statements that use time.After with a long duration, and if those select statements normally terminate quickly, then you will steadily accumulate memory dedicated to timers. And that is why the documentation already says "The underlying Timer is not recovered by the garbage collector until the timer fires. If efficiency is a concern, use NewTimer instead and call Timer.Stop if the timer is no longer needed."

But it's perfectly fine to use time.After if you don't run the select statement many times, or if the duration of the time.After is short, or if the code often times out via time.After rather than because data is sent on one of the other channels.

@ianlancetaylor ianlancetaylor added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Dec 5, 2020
@snadrus
Copy link
Author

snadrus commented Dec 9, 2020

That's quite a list of undocumented gotchas. If you're content with it, then I suppose we can close this bug.

@snadrus snadrus closed this as completed Dec 9, 2020
@ianlancetaylor
Copy link
Contributor

I only count a single gotcha, and it is documented.

@snadrus
Copy link
Author

snadrus commented Dec 9, 2020

That single root cause is 3 "use" gotchas;

  • Used too frequently
  • Used with too long a delay vs use
  • Used in places with "too few" timeout failures

@ianlancetaylor
Copy link
Contributor

In order to have a real problem, all three must be true.

@golang golang locked and limited conversation to collaborators Dec 9, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Documentation FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

5 participants