Commit Graph

49 Commits

Author SHA1 Message Date
Dan Balasescu 7bc8908ca9 Partial everything 2022-11-27 00:00:27 +09:00
Dean Herbert 98938821e5 Merge branch 'master' into beatmap-update-flow 2022-06-30 16:44:17 +09:00
Dean Herbert 18d465eff7 Guard against `NaN` star difficulty results 2022-06-29 21:02:29 +09:00
Dean Herbert 30b3973c9f Difficulty cache invalidation flow 2022-06-24 21:02:38 +09:00
Dean Herbert c179127670 Remove unused bindable retrieval flow 2022-06-24 17:09:56 +09:00
Dean Herbert 0755430006 Use `AddOnce` for update calls 2022-06-24 17:09:56 +09:00
Dean Herbert ef258122d2 Move `GetDifficultyRating` helper method to `StarDifficulty` 2022-06-23 19:51:58 +09:00
Dean Herbert b068df2149 Enable NRT on `BeatmapDiffiultyCache` 2022-06-23 19:51:58 +09:00
Dan Balasescu f8830c6850 Automated #nullable processing 2022-06-17 16:37:17 +09:00
Dean Herbert 86b2ac3217 Remove unnecessary `Ruleset` null check in `BeatmapDifficultyCache` 2022-01-13 13:19:49 +09:00
Dean Herbert 76670a8faa Fix `BeatmapDifficultyCache` not working with detached beatmaps 2022-01-12 17:00:17 +09:00
Dean Herbert 00177a3ae1 Update usages to new naming 2022-01-06 22:54:43 +09:00
Dean Herbert 3ea7588a91 Update continuation usages to use `GetCompletedResult` 2022-01-06 22:53:07 +09:00
Dean Herbert 73b40e6833 Replace usage of `.Result` with `.WaitSafelyForResult` 2022-01-04 11:51:41 +09:00
Dean Herbert 8d9c37a825 Merge branch 'master' into primary-key-consistency 2021-12-08 21:34:38 +09:00
Dean Herbert bbd3ea5b77 Update all actual usages of `RulesetInfo.ID` to use `OnlineID` instead 2021-11-24 15:50:26 +09:00
Dean Herbert 729f681938 Update cases where equality can be used instead of primary key equality 2021-11-24 12:49:57 +09:00
Bartłomiej Dach a7e45a9098
Log all non-cancellation errors in difficulty cache 2021-11-20 17:32:40 +01:00
Bartłomiej Dach 15feb17da8
Change difficulty cache storage type to nullable
The recent changes related to adding support for working beatmap load
cancellation exposed a flaw in the beatmap difficulty cache. With the
way the difficulty computation logic was written, any error in the
calculation process (including beatmap load timeout, or cancellation)
would result in a 0.00 star rating being permanently cached in memory
for the given beatmap.

To resolve, change the difficulty cache's return type to nullable.
In failure scenarios, `null` is returned, rather than
`default(StarDifficulty)` as done previously.
2021-11-20 17:00:50 +01:00
Dean Herbert 83b4625bd5 Replace existing cases with new helper method 2021-11-19 22:15:41 +09:00
Bartłomiej Dach 8b134914cf
Merge branch 'master' into beatmap-cancellation-token 2021-11-17 21:52:30 +01:00
Dean Herbert 7c2e79f911 Update all simple cases of switching to `IWorkingBeatmap` 2021-11-17 20:56:57 +09:00
Dean Herbert 6cca657a2d Standardise naming of `CancellationToken` parameters 2021-11-16 14:45:51 +09:00
Dean Herbert 53c0682a08 Merge branch 'master' into beatmap-cancellation-token 2021-11-16 14:43:13 +09:00
Dean Herbert 6a098a8634 Rename `BeatmapInfo.OnlineBeatmapID` to `OnlineID` to match interface 2021-11-12 17:46:24 +09:00
Tollii eb7d04bc77 Add cancellation token support for beatmap difficulty calculation. 2021-11-06 00:21:29 +01:00
Dean Herbert 08b0ffad50 Fix incorrect check for local beatmap in `BeatmapDifficultyCache`
This was correct in the WIP branch I have, but pulled out alone (where
usages of `ToBeatmapInfo` still exist) it was not enough.
2021-11-03 03:12:52 +09:00
Dean Herbert 7583435901 Refactor `BeatmapDifficultyCache` to work with `IBeatmapInfo` 2021-10-29 16:45:10 +09:00
Dean Herbert 599d82e383 Avoid returning a live `IEnumerable` 2021-10-05 17:01:07 +09:00
smoogipoo 593da79bbc Further asyncify load process 2021-10-05 11:26:13 +09:00
Dean Herbert ec61c3c5ee Rename all remaining cases 2021-10-03 00:55:29 +09:00
Bartłomiej Dach 995338029c
Fix difficulty cache lookups sharing underlying mod instances
`DifficultyCacheLookup`s were storing raw `Mod` instances into their
`OrderedMods` field. This could cause the cache lookups to wrongly
succeed in cases of mods with settings. The particular case that
triggered this fix was Difficulty Adjust.

Because the difficulty cache is backed by a dictionary, there are two
stages to the lookup; first `GetHashCode()` is used to find the
appropriate hash bucket to look in, and then items from that hash bucket
are compared against the key being searched for via the implementation
of `Equals()`.

As it turns out, the first hashing step ended up being the saving grace
in most cases, as the hash computation included the values of the mod
settings. But the Difficulty Adjust failure case was triggered by the
quirk that `GetHashCode(0) == GetHashCode(null) == 0`.

In such a case, the `Equals()` fallback was used. But as it turns out,
because the `Mod` instance stored to lookups was not cloned and
therefore potentially externally mutable, it could be polluted after
being stored to the dictionary, and therefore breaking the equality
check. Even though all of the setting values were compared, the hash
bucket didn't match the actual contents of the lookup anymore (because
they were mutated externally, e.g. by the user changing the mod setting
values in the mod settings overlay).

To resolve, clone out the mod structure before creating all difficulty
lookups.
2021-08-21 15:50:33 +02:00
Salman Ahmed 32ba525555 Track changes to mod settings in beatmap difficulty cache with 100ms debouncing 2021-08-17 05:46:05 +03:00
Salman Ahmed 0291cd5ae2 Consider mod equality in difficulty cache lookup rather than acronym 2021-08-17 04:27:43 +03:00
Salman Ahmed e0728a6e19 Make `BeatmapDifficultyCache.GetDifficultyAsync` virtual 2021-05-14 15:52:36 +03:00
Dean Herbert 5fa9bf61b6 Update xmldoc 2021-02-25 16:22:40 +09:00
Dean Herbert 03771ce8ec Allow determining a BeatmapDifficultyCache's bindable return's completion state via nullability 2021-02-25 16:19:01 +09:00
Dean Herbert 8a0b975d71 Fix deadlock scenario when calculating fallback difficulty
The previous code would run a calcaulation for the beatmap's own ruleset
if the current one failed. While this does make sense, with the current
way we use this component (and the implementation flow) it is quite unsafe.

The to the call on `.Result` in the `catch` block, this would 100%
deadlock due to the thread concurrency of the `ThreadedTaskScheduler`
being 1. Even if the nested run could be run inline (it should be), the
task scheduler won't even get to the point of checking whether this is
feasible due to it being saturated by the already running task.

I'm not sure if we still need this fallback lookup logic. After removing
it, it's feasible that 0 stars will be returned during the scenario that
previously caused a deadlock, but I don't necessarily think this is
incorrect. There may be another reason for this needing to exist which
I'm not aware of (diffcalc?) but if that's the case we may want to move
the try-catch handling to the point of usage.

To reproduce the deadlock scenario with 100% success (the repro
instructions in the linked issue aren't that simple and require some
patience and good timing), the main portion of the lookup can be changed
to randomly trigger a nested lookup:

```
if (RNG.NextSingle() > 0.5f)
    return GetAsync(new
DifficultyCacheLookup(key.Beatmap, key.Beatmap.Ruleset,
key.OrderedMods)).Result;
else
    return new StarDifficulty(attributes);
```

After switching beatmap once or twice, pausing debug and viewing the
state of threads should show exactly what is going on.
2021-01-14 18:25:34 +09:00
Dean Herbert 6cc0bf17a9 Add explicit lock object and some xmldoc for clarity 2020-11-10 14:31:52 +09:00
smoogipoo 66ea1572c7 Fix unsafe list manipulation in BeatmapDifficultyCache 2020-11-10 01:10:00 +09:00
Bartłomiej Dach 6d4bb4316c Fix difficulty retrieval for online-sourced beatmaps 2020-11-08 00:12:25 +01:00
Dean Herbert c1c3d37720 Remove non-null assert 2020-11-06 17:24:28 +09:00
Dean Herbert f51cb0dd14 Add ruleset fallback logic into cache lookup class 2020-11-06 16:58:53 +09:00
Dean Herbert c5b172d0dd Remove synchronous lookup path from BeatmapDifficultyCache 2020-11-06 14:53:15 +09:00
Dean Herbert b69ada64e8 Update BeatmapDifficultyCache to use base implementation logic 2020-11-06 14:31:21 +09:00
Dean Herbert 517a656899 Move StarDifficulty to own file 2020-11-06 13:51:25 +09:00
Dean Herbert 74ca2faa31 Remove unused using 2020-11-06 13:48:06 +09:00
Dean Herbert 0103b12575 Add basic base class to begin to standardise function across caching components 2020-11-06 13:26:39 +09:00
Dean Herbert 5113d4af8f Rename BeatmapDifficultyManager to BeatmapDifficultyCache 2020-11-06 13:14:29 +09:00