Skip to content

Commit

Permalink
Prevent mirrors from tanking to 0 on a single beatmapset download
Browse files Browse the repository at this point in the history
  • Loading branch information
cmyui committed Jun 27, 2024
1 parent 97ff7e1 commit eeac6c2
Showing 1 changed file with 15 additions and 4 deletions.
19 changes: 15 additions & 4 deletions app/adapters/osu_mirrors/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import logging
from datetime import datetime
from typing import TypeGuard

from app.adapters.osu_mirrors.backends import AbstractBeatmapMirror
from app.adapters.osu_mirrors.backends.mino import MinoMirror
from app.adapters.osu_mirrors.backends.nerinyan import NerinyanMirror
from app.adapters.osu_mirrors.backends.osu_direct import OsuDirectMirror
Expand All @@ -22,26 +24,34 @@
)


def is_valid_zip_file(content: bytes | None) -> TypeGuard[bytes]:
return content is not None and content.startswith(ZIP_FILE_HEADER)


async def fetch_beatmap_zip_data(beatmapset_id: int) -> bytes | None:
"""\
Fetch a beatmapset .osz2 file by any means necessary, balancing upon
multiple underlying beatmap mirrors to ensure the best possible
availability and performance.
"""
started_at = datetime.now()
prev_mirror: AbstractBeatmapMirror | None = None

await BEATMAP_SELECTOR.update_all_mirror_and_selector_weights()

while True:
mirror = BEATMAP_SELECTOR.select_mirror()
if mirror is prev_mirror:
# don't allow the same mirror to be run twice, to help
# prevent loops which cause the mirror to lose all weighting
# because of an error on a single beatmapset
continue

beatmap_zip_data: bytes | None = None
try:
beatmap_zip_data = await mirror.fetch_beatmap_zip_data(beatmapset_id)

if beatmap_zip_data is not None and (
not beatmap_zip_data.startswith(ZIP_FILE_HEADER)
or len(beatmap_zip_data) < 20_000
):
if not is_valid_zip_file(beatmap_zip_data):
raise ValueError("Received bad osz2 data from mirror")
except Exception as exc:
ended_at = datetime.now()
Expand All @@ -65,6 +75,7 @@ async def fetch_beatmap_zip_data(beatmapset_id: int) -> bytes | None:
"beatmapset_id": beatmapset_id,
},
)
prev_mirror = mirror
continue
else:
break
Expand Down

0 comments on commit eeac6c2

Please sign in to comment.