-
Notifications
You must be signed in to change notification settings - Fork 67
Implement event-based contexts for view changes and timeouts #74
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
Conversation
6a18078 to
2ae3918
Compare
If we are going to use a view context for voting, then we need to be in the correct view before we start the voting process. Otherwise, the vote could be canceled by the following view change.
This decouples contexts from the synchronizer and makes them listen for events on the event loop.
This commit aims to make the eventloop more flexible by allowing both async and sync handlers again. Handlers can be made async by passing a RunAsync handler option. Furthermore, observers have been replaced by a WithPriority handler option.
2ae3918 to
318c166
Compare
Smart contexts that listen for timeouts
Now options are set by calling a WithOptions method on which RegisterHandler can be called afterwards.
ddf8d8a to
c58cb4f
Compare
The options struct is used for configuration that is shared between modules. With this commit, we no longer need to add new options as a field in the options struct, but allow packages to register new options at will. The options are stored in an array and indexed using the option ID, so the performance impact should be minimal.
copylocks: <field> passes lock by value: github.com/relab/hotstuff/modules.Options contains sync.Mutex (govet)
Codecov Report
❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more. @@ Coverage Diff @@
## master #74 +/- ##
==========================================
- Coverage 72.42% 71.91% -0.52%
==========================================
Files 61 63 +2
Lines 6168 6305 +137
==========================================
+ Hits 4467 4534 +67
- Misses 1401 1458 +57
- Partials 300 313 +13
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 8 files with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
meling
left a comment
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.
Mostly nice, but please check my comments. We may need to discuss some of them.
| } | ||
|
|
||
| // UnregisterObserver unregister a handler. | ||
| // Deprecated: use UnregisterHandler instead. |
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 it is okay to just delete the method, since it is not used in the codebase.
| eventloop.AddEvent(synchronizer.ViewChangeEvent{View: 0}) | ||
|
|
||
| if ctx.Err() != nil { | ||
| t.Error("Context cancelled") |
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.
Shouldn't this check if the error was actually a context cancelled error?
If we are going to use a view context for voting, then we need to be in the correct view before we start the voting process. Otherwise, the vote could be canceled by the following view change.
This decouples contexts from the synchronizer and makes them listen for events on the event loop.
This commit aims to make the eventloop more flexible by allowing both async and sync handlers again. Handlers can be made async by passing a RunAsync handler option. Furthermore, observers have been replaced by a WithPriority handler option.
Smart contexts that listen for timeouts
Now options are set by calling a WithOptions method on which RegisterHandler can be called afterwards.
The options struct is used for configuration that is shared between modules. With this commit, we no longer need to add new options as a field in the options struct, but allow packages to register new options at will. The options are stored in an array and indexed using the option ID, so the performance impact should be minimal.
copylocks: <field> passes lock by value: github.com/relab/hotstuff/modules.Options contains sync.Mutex (govet)
This commit introduces new names for the handler options and updates the documentation, in order to address code review comments.
The mutex was only needed because s.View() was being accessed by a timer goroutine.
This indirect approach causes confusion IMO.
This is not used and not documented; we can add this back if we find it will be useful in the future.
This aims to benchmark the event loop's processEvent method. ```sh % go test -v -run x -bench BenchmarkEventLoopWithUnsafe -count=20 -benchmem goos: darwin goarch: arm64 pkg: github.com/relab/hotstuff/eventloop BenchmarkEventLoopWithUnsafeRunInAddEventHandlers BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 347619 3456 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 344972 3444 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 348097 3422 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 349779 3452 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 343992 3464 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 345339 3426 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 347434 3424 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 342284 3478 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 346063 3451 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 350206 3426 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 347432 3377 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 360820 3313 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 360350 3324 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 359367 3320 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 361963 3314 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 355348 3323 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 362910 3417 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 347767 3456 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 345124 3447 ns/op 480 B/op 20 allocs/op BenchmarkEventLoopWithUnsafeRunInAddEventHandlers-12 347486 3424 ns/op 480 B/op 20 allocs/op PASS ok github.com/relab/hotstuff/eventloop 25.025s ```
This PR implements two functions,
ViewContextandTimeoutContext. They return contexts that can be used for operations that should be canceled upon reaching a specific view, or when a timeout occurs.Implementing these contexts require changes to the event loop. Specifically, we have to reintroduce asynchronous handlers, as the contexts must be able to react to new events to cancel tasks that may be running on the event loop itself. I chose to refactor the event loop handlers by adding some handler options. Currently, the only options are
RunAsyncandWithPriority.RunAsyncmakes the handler execute as part ofAddEvent.WithPriorityeffectively turns the handler into an "observer". The idea is that handlers that don't require much time to run can use theWithPriorityoption to be executed before the other handlers. I am deprecating the Observer functionality in favor of the priority options.