mirror of
https://github.com/ppy/osu.git
synced 2025-01-06 04:13:11 +08:00
Fix aborting an APIRequest
potentially resulting in incorrect success
This commit is contained in:
parent
2a94fc214f
commit
3a5324c947
@ -86,8 +86,6 @@ namespace osu.Game.Online.API
|
||||
/// </summary>
|
||||
private APIRequestCompletionState completionState;
|
||||
|
||||
private Action pendingFailure;
|
||||
|
||||
public void Perform(IAPIProvider api)
|
||||
{
|
||||
if (!(api is APIAccess apiAccess))
|
||||
@ -99,29 +97,23 @@ namespace osu.Game.Online.API
|
||||
API = apiAccess;
|
||||
User = apiAccess.LocalUser.Value;
|
||||
|
||||
if (checkAndScheduleFailure())
|
||||
return;
|
||||
if (isFailing) return;
|
||||
|
||||
WebRequest = CreateWebRequest();
|
||||
WebRequest.Failed += Fail;
|
||||
WebRequest.AllowRetryOnTimeout = false;
|
||||
WebRequest.AddHeader("Authorization", $"Bearer {API.AccessToken}");
|
||||
|
||||
if (checkAndScheduleFailure())
|
||||
return;
|
||||
if (isFailing) return;
|
||||
|
||||
if (!WebRequest.Aborted) // could have been aborted by a Cancel() call
|
||||
{
|
||||
Logger.Log($@"Performing request {this}", LoggingTarget.Network);
|
||||
WebRequest.Perform();
|
||||
}
|
||||
|
||||
if (checkAndScheduleFailure())
|
||||
return;
|
||||
if (isFailing) return;
|
||||
|
||||
PostProcess();
|
||||
|
||||
API.Schedule(TriggerSuccess);
|
||||
TriggerSuccess();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -141,7 +133,10 @@ namespace osu.Game.Online.API
|
||||
completionState = APIRequestCompletionState.Completed;
|
||||
}
|
||||
|
||||
if (API == null)
|
||||
Success?.Invoke();
|
||||
else
|
||||
API.Schedule(() => Success?.Invoke());
|
||||
}
|
||||
|
||||
internal void TriggerFailure(Exception e)
|
||||
@ -154,7 +149,10 @@ namespace osu.Game.Online.API
|
||||
completionState = APIRequestCompletionState.Failed;
|
||||
}
|
||||
|
||||
if (API == null)
|
||||
Failure?.Invoke(e);
|
||||
else
|
||||
API.Schedule(() => Failure?.Invoke(e));
|
||||
}
|
||||
|
||||
public void Cancel() => Fail(new OperationCanceledException(@"Request cancelled"));
|
||||
@ -163,11 +161,8 @@ namespace osu.Game.Online.API
|
||||
{
|
||||
lock (completionStateLock)
|
||||
{
|
||||
// while it doesn't matter if code following this check is run more than once,
|
||||
// this avoids unnecessarily performing work where we are already sure the user has been informed.
|
||||
if (completionState != APIRequestCompletionState.Waiting)
|
||||
return;
|
||||
}
|
||||
|
||||
WebRequest?.Abort();
|
||||
|
||||
@ -193,29 +188,20 @@ namespace osu.Game.Online.API
|
||||
}
|
||||
|
||||
Logger.Log($@"Failing request {this} ({e})", LoggingTarget.Network);
|
||||
pendingFailure = () => TriggerFailure(e);
|
||||
checkAndScheduleFailure();
|
||||
TriggerFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checked for cancellation or error. Also queues up the Failed event if we can.
|
||||
/// Whether this request is in a failing or failed state.
|
||||
/// </summary>
|
||||
/// <returns>Whether we are in a failed or cancelled state.</returns>
|
||||
private bool checkAndScheduleFailure()
|
||||
private bool isFailing
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (completionStateLock)
|
||||
{
|
||||
if (pendingFailure == null)
|
||||
return completionState == APIRequestCompletionState.Failed;
|
||||
}
|
||||
|
||||
if (API == null)
|
||||
pendingFailure();
|
||||
else
|
||||
API.Schedule(pendingFailure);
|
||||
|
||||
pendingFailure = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
private class DisplayableError
|
||||
|
Loading…
Reference in New Issue
Block a user