1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-19 03:33:20 +08:00

Use cache for beatmap lookups on spectate screen

@peppy noticed recently that attempting to spectate just a few users was
very likely to end up in requests very quickly being rejected with code
429 ("Too Many Requests").

I'm somewhat certain that the reason for that is that a significant
number of players is wont to retry a lot in quick succession. That means
that spectator server is going to note a lot of gameplay start and end
messages in quick succession, too. And as it turns out, every gameplay
start would end up triggering a new beatmap set fetch request:

	ccf1acce56/osu.Game/Screens/Spectate/SpectatorScreen.cs (L131-L134)
	ccf1acce56/osu.Game/Screens/Play/SoloSpectatorScreen.cs (L168-L172)
	ccf1acce56/osu.Game/Screens/Play/SoloSpectatorScreen.cs (L243-L256)

To attempt to curtail that, use the beatmap cache instead, which should
prevent these unnecessary requests from firing in the first place,
therefore reducing the chance of the client getting throttled.

This technically means that a different endpoint is used to fetch the
data (`GET /beatmaps/?ids[]=` rather than `GET
/beatmapsets/lookup?beatmap_id={id}`), but docs claim that both should
return the same data, and it looks to work fine in practice.
This commit is contained in:
Bartłomiej Dach 2024-09-23 11:53:32 +02:00
parent ccf1acce56
commit 4b349ba387
No known key found for this signature in database

View File

@ -3,6 +3,7 @@
using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -13,12 +14,11 @@ using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables.Cards;
using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Spectator;
using osu.Game.Overlays;
@ -34,7 +34,7 @@ namespace osu.Game.Screens.Play
public partial class SoloSpectatorScreen : SpectatorScreen, IPreviewTrackOwner
{
[Resolved]
private IAPIProvider api { get; set; } = null!;
private BeatmapLookupCache beatmapLookupCache { get; set; } = null!;
[Resolved]
private PreviewTrackManager previewTrackManager { get; set; } = null!;
@ -60,7 +60,7 @@ namespace osu.Game.Screens.Play
/// </summary>
private SpectatorGameplayState? immediateSpectatorGameplayState;
private GetBeatmapSetRequest? onlineBeatmapRequest;
private ScheduledDelegate? beatmapFetchCallback;
private APIBeatmapSet? beatmapSet;
@ -210,7 +210,7 @@ namespace osu.Game.Screens.Play
private void clearDisplay()
{
watchButton.Enabled.Value = false;
onlineBeatmapRequest?.Cancel();
beatmapFetchCallback?.Cancel();
beatmapPanelContainer.Clear();
previewTrackManager.StopAnyPlaying(this);
}
@ -244,15 +244,17 @@ namespace osu.Game.Screens.Play
{
Debug.Assert(state.BeatmapID != null);
onlineBeatmapRequest = new GetBeatmapSetRequest(state.BeatmapID.Value, BeatmapSetLookupType.BeatmapId);
onlineBeatmapRequest.Success += beatmapSet => Schedule(() =>
beatmapLookupCache.GetBeatmapAsync(state.BeatmapID.Value).ContinueWith(t => beatmapFetchCallback = Schedule(() =>
{
this.beatmapSet = beatmapSet;
beatmapPanelContainer.Child = new BeatmapCardNormal(this.beatmapSet, allowExpansion: false);
checkForAutomaticDownload();
});
var beatmap = t.GetResultSafely();
api.Queue(onlineBeatmapRequest);
if (beatmap?.BeatmapSet == null)
return;
beatmapSet = beatmap.BeatmapSet;
beatmapPanelContainer.Child = new BeatmapCardNormal(beatmapSet, allowExpansion: false);
checkForAutomaticDownload();
}));
}
private void checkForAutomaticDownload()