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

Stricter Control over Starting/Stopping Lifecycle #994

Merged

Conversation

JacobOaks
Copy link
Contributor

Currently, there is nothing preventing somebody from making calls to app.Start and app.Stop when it doesn't make sense, for example calling app.Start or app.Stop twice, or trying to run the application twice concurrently. Because of this lack of control, it's possible for users to cause race conditions and panics (#991) by putting the lifecycle is strange positions.

This PR places a small state machine in Lifecycle so that we can check if calls to (*Lifecycle).Start and (*Lifecycle).Stop make sense before going through. This will disallow starting an already starting/started app, and stopping an already stopping/stopped app. Tests to verify that are also added.

Currently, it is possible for a user to start their app (and thus
its lifecycle) twice. This can lead to panics if the user has
registered any lifecycle hooks (Ref:
uber-go#991).

This change will explicitly keep track of whether a lifecycle
is currently running, under a lock, to ensure that the lifecycle
can never be running twice at the same time.
@codecov
Copy link

codecov bot commented Dec 6, 2022

Codecov Report

Merging #994 (16c7e06) into master (c9b24f8) will decrease coverage by 0.39%.
The diff coverage is 77.77%.

@@            Coverage Diff             @@
##           master     #994      +/-   ##
==========================================
- Coverage   98.71%   98.32%   -0.40%     
==========================================
  Files          39       39              
  Lines        1872     1908      +36     
==========================================
+ Hits         1848     1876      +28     
- Misses         17       25       +8     
  Partials        7        7              
Impacted Files Coverage Δ
internal/lifecycle/lifecycle.go 95.58% <77.77%> (-4.42%) ⬇️

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

type appState int

const (
notRunning appState = iota
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: consider renaming this to stopped.

l.mu.Lock()
if l.state != started && l.state != incompleteStart {
l.mu.Unlock()
return errors.New("attempted to stop lifecycle when not running")
Copy link
Contributor

Choose a reason for hiding this comment

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

this error message might make more sense if you printed the current state of l.state rather than just "not running" here since it could be either not running or starting or stopping.

Copy link
Contributor

@sywhang sywhang left a comment

Choose a reason for hiding this comment

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

LGTM

@JacobOaks JacobOaks merged commit 94f1a09 into uber-go:master Dec 6, 2022
jasonmills pushed a commit to jasonmills/fx that referenced this pull request Dec 7, 2022
Currently, there is nothing preventing somebody from making calls to
`app.Start` and `app.Stop` when it doesn't make sense, for example
calling `app.Start` or `app.Stop` twice, or trying to run the
application twice concurrently. Because of this lack of control, it's
possible for users to cause race conditions and panics (uber-go#991) by putting
the lifecycle is strange positions.

This PR places a small state machine in `Lifecycle` so that we can check
if calls to `(*Lifecycle).Start` and `(*Lifecycle).Stop` make sense
before going through. This will disallow starting an already
starting/started app, and stopping an already stopping/stopped app.
Tests to verify that are also added.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants