-
Notifications
You must be signed in to change notification settings - Fork 674
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
Make bootstrapping handle its own timeouts #3410
Conversation
e2641d7
to
09ad764
Compare
25122c6
to
b54e285
Compare
31d051e
to
c25a68d
Compare
snow/engine/common/timer.go
Outdated
} | ||
|
||
// RegisterTimeout fires the function the timeout handler is initialized with no later than the given timeout. | ||
func (th *timeoutHandler) RegisterTimeout(d time.Duration) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just moved this code section from handler.go
snow/engine/common/timer.go
Outdated
newTimer: func(d time.Duration) (<-chan time.Time, func() bool) { | ||
timer := time.NewTimer(d) | ||
return timer.C, timer.Stop | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reason for specifying this function here rather than just using time.NewTimer
directly?
It looks like we replace this with an identical implementation in one of our test cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because I needed it for the tests :-)
snow/engine/common/timer_test.go
Outdated
}, | ||
}, | ||
} { | ||
t.Run(testCase.desc, func(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to remove clock
from these tests?
What do you think of adding test cases for multiple timeouts w/ and w/o preemption?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added two tests as requested, but I need the clock for these tests.
9be93a5
to
fe44d95
Compare
4f949b8
to
bdf0063
Compare
snow/engine/common/timer.go
Outdated
timer := th.newTimer(d) | ||
defer timer.Stop() | ||
|
||
defer th.onTimeout() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I feel like this makes a bit more sense to just be called inline at the end of the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inlined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this inlining may need to be pushed from your local branch, it still seems to use the defer
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I thought you meant to inline relinquishing the pending token.
214ed68
to
a7b3ab4
Compare
@StephenButtolph thanks for the review, addressed your comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final nits then lgtm
snow/engine/common/timer.go
Outdated
timer := th.newTimer(d) | ||
defer timer.Stop() | ||
|
||
defer th.onTimeout() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this inlining may need to be pushed from your local branch, it still seems to use the defer
.
Currently, an engine registers timeouts into the handler, which schedules the timeouts on behalf of the the engine. The handler then notifies the engine when the timeout expired. However, the only engine that uses this mechanism is the bootstrapping engine, and not the other engine types such as the snowman and state sync engines. It therefore makes sense to consolidate the timeout handling instead of delegating them to the handler. By moving the timeout handling closer to the bootstrapper, we can make the API of the common.Engine be slimmer by removing the Timeout() method from it. Signed-off-by: Yacov Manevich <[email protected]>
Signed-off-by: Yacov Manevich <[email protected]>
Signed-off-by: Yacov Manevich <[email protected]>
5071701
to
6148a8b
Compare
Signed-off-by: Yacov Manevich <[email protected]>
d4a443a
to
2f5466f
Compare
Signed-off-by: Yacov Manevich <[email protected]>
Signed-off-by: Yacov Manevich <[email protected]>
Why this should be merged
Currently, an engine registers timeouts into the handler, which schedules the timeouts on behalf of the the engine.
The handler then notifies the engine when the timeout expired.
However, the only engine that uses this mechanism is the bootstrapping engine, and not the other engine types such as the snowman and state sync engines.
It therefore makes sense to consolidate the timeout handling instead of delegating them to the handler.
By moving the timeout handling closer to the bootstrapper, we can make the API of the common.Engine be slimmer by removing the Timeout() method from it.
How this works
I refactored the timeout logic and decoupled it from the handler.
I also re-implemented the timeout mechanism in order to be more robust and testable.
How this was tested
The node successfully finished bootstrapping and there were no data races observed in its log.