-
Notifications
You must be signed in to change notification settings - Fork 4.6k
internal/grpcsync: support two ways to schedule a callback with the serializer #7408
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
556f171 to
290191e
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #7408 +/- ##
==========================================
- Coverage 81.45% 81.38% -0.08%
==========================================
Files 348 350 +2
Lines 26752 26845 +93
==========================================
+ Hits 21792 21848 +56
- Misses 3773 3799 +26
- Partials 1187 1198 +11
|
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.
This LGTM but one minor simplification suggestion. Naming question: Maybe is OK and what I originally proposed, but how do you feel about TrySchedule?
balancer_wrapper.go
Outdated
| func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) error { | ||
| errCh := make(chan error) | ||
| ok := ccb.serializer.Schedule(func(ctx context.Context) { | ||
| errCh := make(chan error, 1) |
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.
This can stay unbounded, and maybe improved a little:
func uCCS() {
errCh := make(chan error)
defer close(errCh)
uccs := ...
onFailure := func() {}
...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.
We need to block on reading from this channel when the uccs callback is successfully scheduled on the serializer (because we want to handle state updates inline). But if we don't send something on the channel from the onFailure func, the last line return <-errCh will block forever, right? This is equivalent, isn't it? https://go.dev/play/p/GHPD4MLhis6
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.
Um, yes, I tried to simplify too much, oops. You can still make the channel unbuffered (sorry for saying "unbounded"), and not defer the close but call close in the onFailure:
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.
Done.
| // Handle the update in a blocking fashion. | ||
| done := make(chan struct{}) | ||
| ok = b.serializer.Schedule(func(context.Context) { | ||
| errCh := make(chan error, 1) |
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.
Similar here as above.
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 can't make it unbuffered here because if ScheduleOr fails, it will call onFailure inline and this means that the write to the channel on line 327 errCh <- errBalancerClosed will happen before the read on line 330. Therefore it will just hang.
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.
Ah yes, that makes sense.
The earlier API to add callbacks to the serializer,
Schedule, was returning aboolto indicate whether or not the callback was added to the serializer. This had the following problems:Schedulefails, while for most of the others, it is totally OK for the call toScheduleto fail.This PR splits the API into two:
MaybeSchedule: A best effort API that fails silently if the serializer is closedScheduleOr: An API which runs anonFailurefunc if the callback cannot be scheduledRELEASE NOTES: none