Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ private[group] class MemberMetadata(var memberId: String,
def shouldKeepAlive(deadlineMs: Long): Boolean = {
if (isAwaitingJoin)
!isNew || latestHeartbeat + GroupCoordinator.NewMemberJoinTimeoutMs > deadlineMs
else awaitingSyncCallback != null ||

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

replaced awaitingSyncCallback != null with isAwaitingSync

else if (isNew || isAwaitingSync)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

In onCompleteJoin, we call

  1. group.maybeInvokeJoinCallback(member, joinResult)
  2. completeAndScheduleNextHeartbeatExpiration(group, member)
  3. member.isNew = false

In 1. we ultimately set member.isAwaitingJoin to false, so we never reach the first branch in this case.

I refactored this a bit to reflect what (I think) makes sense: we want to always return true in the special cases of a) awaiting Sync, and b) between awaiting the Join and awaiting the Sync, ie, when isNew = true -- otherwise, we fall back to the usual case, ie, just return whether we've seen a heartbeat within the deadline or not

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Alternatively we could leave this method alone and change the ordering in onCompleteJoin to

member.isNew = false
completeAndScheduleNextHeartbeatExpiration(group, member)
group.maybeInvokeJoinCallback(member, joinResult)

I think this also makes sense, and might be a bit more clear, but I'd want to verify that it's ok to move the heartbeat completion to before the group.maybeInvokeJoinCallback

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm for simplifying if possible. What I am thinking is the following:

if (isNew)
  // New members are expired after the static join timeout
  latestHeartbeat + GroupCoordinator.NewMemberJoinTimeoutMs > deadlineMs
else if (isAwaitingJoin || isAwaitingSync)
  // Don't remove members as long as they have a request in purgatory
  true
else
  // Otherwise check for session expiration
  latestHeartbeat + sessionTimeoutMs > deadlineMs

Then I think this works with the reordering you suggested above:

member.isNew = false
completeAndScheduleNextHeartbeatExpiration(group, member)
group.maybeInvokeJoinCallback(member, joinResult)

Upon rebalance completion, the first check will fail since we set isNew to false and the second check will succeed because we haven't cleared the join callback yet. What do you think?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ok yeah I like that, the shouldKeepAlive logic is much easier to follow

true
else
latestHeartbeat + sessionTimeoutMs > deadlineMs
}

Expand Down