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

refactor: use Channels as queueing mechanism for periodic websocket messages #11092

Conversation

cvium
Copy link
Member

@cvium cvium commented Mar 2, 2024

The old implementation used async void as the signature for the event handlers, which might lead to thread pool exhaustion as handlers would fetch the data synchronously despite the async signature on GetDataToSend. Furthermore, on every event, the list of active connections were retrieved inside a lock statement, which could also lead to threads being blocked during high traffic scenarios.

Queueing a bool is not great design, but this change only aims to alleviate the thread pool exhaustion.

Issues
Might fix #7783, but I have not been able to reproduce it.

…essages

The old implementation used async void as the signature for the event handlers, which might lead to thread pool exhaustion as handlers would fetch the data synchronously despite the async signature on GetDataToSend. Furthermore, on every event, the list of active connections were retrieved inside a `lock` statement, which could also lead to threads being blocked during high traffic scenarios.

Queueing a bool is not great design, but this change only aims to alleviate the thread pool exhaustion.
@JPVenson JPVenson added bug Something isn't working backend Related to the server backend labels Mar 3, 2024
@@ -137,63 +144,66 @@ protected void SendData(bool force)

private async Task HandleMessages()
{
await foreach (var force in _channel.Reader.ReadAllAsync())
while (await _channel.Reader.WaitToReadAsync().ConfigureAwait(false))
Copy link
Member

Choose a reason for hiding this comment

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

Why not keeping ReadAllAsync? looking at the source code it does the same WaitToRead/TryRead

Copy link
Member Author

Choose a reason for hiding this comment

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

We don't really need an IAsyncEnumerable. That one is mostly for when you know the Writer will complete at some point. At least according to the docs.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

One is a few loops, the other is looping over an async enumerator, so not quite the same. We don't need an IAsyncEnumerable.

@crobibero crobibero merged commit eae031a into jellyfin:master Mar 18, 2024
23 checks passed
SourSulfur pushed a commit to SourSulfur/jellyfin that referenced this pull request Apr 19, 2024
SourSulfur pushed a commit to SourSulfur/jellyfin that referenced this pull request Apr 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend Related to the server backend bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Issue][10.8.X]: Dashboard causes high CPU usage and thread multiplication
5 participants