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

Fixes timer resources leak in CountdownToGenesis #7175

Merged
merged 3 commits into from
Sep 4, 2020

Conversation

farazdagi
Copy link
Contributor

@farazdagi farazdagi commented Sep 4, 2020

What type of PR is this?

Bug fix

What does this PR do? Why is it needed?

  • When reviewing our timer usage discovered the following issues in CountdownToGenesis():
    • <-time.After() was invoked on each loop iteration, and it is not GC'ed up until event fires (so, resources are accumulated as on each tick of the other ticker, loop progresses, and on a select - we generate another time.After channel). What makes things even less optimized: we do not need that time.After case -- at all. This PR just checks on each iteration whether we can get out of the loop, w/o any time.After
    • Clean way to use ticker := NewTicker() is to call ticker.Stop() when ticker is done. This PR makes sure that both the original ticker (one that uses config.GenesisCountdownInterval duration) and the more granular one are closed at the end of the function.
    • New timer (one that has granularity of 1 second), is created every iteration (instead of being created just once, and tick every second):
      timeRemaining := genesisTime.Sub(currentTime)
      if timeRemaining <= 2*time.Minute {
      ticker = time.NewTicker(time.Second)
      }

Which issues(s) does this PR fix?

N/A

Other notes for review

  • cc @rauljordan
  • Code in question:
    func CountdownToGenesis(ctx context.Context, genesisTime time.Time, genesisValidatorCount uint64) {
    ticker := time.NewTicker(params.BeaconConfig().GenesisCountdownInterval)
    timeTillGenesis := genesisTime.Sub(roughtime.Now())
    logFields := logrus.Fields{
    "genesisValidators": fmt.Sprintf("%d", genesisValidatorCount),
    "genesisTime": fmt.Sprintf("%v", genesisTime),
    }
    for {
    select {
    case <-time.After(timeTillGenesis):
    log.WithFields(logFields).Info("Chain genesis time reached")
    return
    case <-ticker.C:
    currentTime := roughtime.Now()
    if currentTime.After(genesisTime) {
    log.WithFields(logFields).Info("Chain genesis time reached")
    return
    }
    timeRemaining := genesisTime.Sub(currentTime)
    if timeRemaining <= 2*time.Minute {
    ticker = time.NewTicker(time.Second)
    }
    if timeRemaining >= time.Second {
    log.WithFields(logFields).Infof(
    "%s until chain genesis",
    timeRemaining.Truncate(time.Second),
    )
    }
    case <-ctx.Done():
    return
    }
    }
    }
  • Minor: test suite has been extended a bit -- to make sure that we have 100% code coverage

@farazdagi farazdagi requested a review from rauljordan September 4, 2020 12:33
@farazdagi farazdagi requested a review from a team as a code owner September 4, 2020 12:33
@farazdagi farazdagi self-assigned this Sep 4, 2020
@farazdagi farazdagi requested review from 0xKiwi and rkapka September 4, 2020 12:33
@farazdagi farazdagi changed the title Fixes timer leak in CountdownToGenesis Fixes timer resources leak in CountdownToGenesis Sep 4, 2020
Copy link
Contributor

@rauljordan rauljordan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @farazdagi this is a nice find. We should be careful with time.After

@prylabs-bulldozer prylabs-bulldozer bot merged commit b6607fa into master Sep 4, 2020
@farazdagi farazdagi deleted the fix-unclosed-timer-in-countdown branch September 8, 2020 12:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants