-
Notifications
You must be signed in to change notification settings - Fork 14
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
Send notifications about score processing completion to clients #157
Conversation
} | ||
} | ||
|
||
private void purgeTimedOutSubscriptions() |
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've added this entire flow to avoid a situation where the subscriber gets backlogged due to the score processor not being able to catch up to incoming scores and accumulates too many subscriptions, causing a cascading failure. I'm not sure how realistic of a scenario this is in practice.
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.
Going to have to see how this plays out post deploy really.
if (subscriptions.TryRemove(scoreProcessed.ScoreId, out var subscription)) | ||
{ | ||
using (subscription) | ||
subscription.InvokeAsync().Wait(); |
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.
The .Wait()
is unfortunate, but I'm not sure how to avoid it.
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.
Probably fine.
As it is undefined behaviour: dotnet/AspNetCore.Docs#6888 `IHubContext<SpectatorClient>` can be used instead.
I've figured out what this was; see ppy/osu#21753 for explanation and proposed fix. |
The class name caught me off-guard and I thought this was doing something extra/weird.
/// <summary> | ||
/// The maximum amount of time to wait for a <see cref="ScoreProcessed"/> message for a given score in milliseconds. | ||
/// </summary> | ||
private const int timeout_interval_ms = 30_000; |
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'll see how this plays out. I have a feeling going higher than this will be what we want eventually (minutes at least) to allow for potential server-side issues/outages.
|
||
foreach (var scoreId in scoreIds) | ||
{ | ||
if (subscriptions.TryGetValue(scoreId, out var subscription) && subscription.TimedOut) |
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.
One thing to watch out for is that CancellationTokenSource.Token
throws an exception if the CTS has been disposed. There could theoretically be a small moment where this TryGetValue()
retrieves the value on this thread, but then the using (subscription)
above runs and only after that does the subscription.TimedOut
check happen.
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 was aware of this, but when I checked the implementation, then I didn't expect an IsCancellationRequested
check to throw after disposal. Maybe bad form relying on implementation details.
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.
No you're correct, I didn't know there was such a discrepancy between Token
and IsCancellationRequested
Note: This is an RFC. It has been tested very lightly. The happy path seems to work, but I'm not sure about the multitude of sad paths. I'm PRing this now to get it out for comments and see how many WTFs I get, as I'm not confident about almost everything in this diff, so I wouldn't necessarily advise to hurry this one up too much.
Testing procedure, for whoever is inclined:
osu
+osu-web
+osu-server-spectator
setuposu
, check out pull mentioned aboveosu-server-spectator
, switch to local checkoutosu-queue-score-statistics
so that it can pick up scores placed in redis byosu-web
patch to apply to game
At this point, every completed play should result in a notification being fired. Aborted plays won't always fire the notification. I'm not sure why yet, I'm going to look into that a bit more still tomorrow if this approach doesn't just get dumpstered immediately.
I'll be adding some self-commentary review comments shortly.