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

Support for new Slic ping/pong frame protocol #3348

Merged
merged 7 commits into from
Jun 13, 2023
Merged

Conversation

bentoi
Copy link
Contributor

@bentoi bentoi commented Jun 12, 2023

This PR implements the proposal from #3273

}

// The ping task is necessarily waiting for the pong frame if the wait for pong TCS is not completed.
Debug.Assert(!_pingTask.IsCompleted);
Copy link
Member

Choose a reason for hiding this comment

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

This looks bogus to me: when the ping task is canceled by DisposeAsync, the _waitForPongFrameTcs is still alive and running.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.

(ref SliceDecoder decoder) => new PongBody(ref decoder),
cancellationToken).ConfigureAwait(false);

_waitForPongFrameTcs.SetResult(pongBody);
Copy link
Member

Choose a reason for hiding this comment

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

This is a synchronous continuation in the "read loop task".

It's dubious to do all this work this in this critical read loop task.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The continuation is just a payload comparison. But fine, I've changed it to run the continuation asynchronously.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've re-worked the code to no longer use a TCS.

// TODO: KeepAlive is called every IdleTimeout / 2 if it's not deferred by a write. Instead, we could
// consider disabling the KeepAlive timer until the pong frame is received.

// If not waiting for a pong frame (_pongIsPending=0), send a new ping frame.
Copy link
Member

Choose a reason for hiding this comment

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

So you fixed the TODO above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I added it to get feedback on it. Opened #3354 to discuss if we want to fix it and how to fix it.

WriteConnectionFrame(FrameType.Pong, new PongBody(pingBody.Payload).Encode);
}

async Task ReadPongFrameAsync(int size, CancellationToken cancellationToken)
Copy link
Member

Choose a reason for hiding this comment

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

When this method returns a faulted Task, the "read loop task" fails and the Slic connection is aborted?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the read loop task awaits ReadPongFrameAsync so it will fail.

However, it doesn't abort the connection directly. Instead, AcceptStreamAsync fails and triggers the protocol connection ShutdownRequested task completion. The client connection or connection pool will start the shutdown sequence and dispose the protocol connection that will dispose the transport connection.

@bentoi bentoi merged commit 8aedc66 into icerpc:main Jun 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants