1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-21 11:22:55 +08:00

Merge pull request #3346 from peppy/api-ref-reduction

Don't use ConcurrentQueue for API
This commit is contained in:
Dean Herbert 2018-09-06 17:55:40 +09:00 committed by GitHub
commit 80bab8e898
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,12 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Net; using System.Net;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Logging; using osu.Framework.Logging;
@ -26,7 +24,7 @@ namespace osu.Game.Online.API
private const string client_id = @"5"; private const string client_id = @"5";
private const string client_secret = @"FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"; private const string client_secret = @"FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk";
private ConcurrentQueue<APIRequest> queue = new ConcurrentQueue<APIRequest>(); private readonly Queue<APIRequest> queue = new Queue<APIRequest>();
/// <summary> /// <summary>
/// The username/email provided by the user when initiating a login. /// The username/email provided by the user when initiating a login.
@ -55,7 +53,13 @@ namespace osu.Game.Online.API
authentication.TokenString = config.Get<string>(OsuSetting.Token); authentication.TokenString = config.Get<string>(OsuSetting.Token);
authentication.Token.ValueChanged += onTokenChanged; authentication.Token.ValueChanged += onTokenChanged;
Task.Factory.StartNew(run, cancellationToken.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); var thread = new Thread(run)
{
Name = "APIAccess",
IsBackground = true
};
thread.Start();
} }
private void onTokenChanged(OAuthToken token) => config.Set(OsuSetting.Token, config.Get<bool>(OsuSetting.SavePassword) ? authentication.TokenString : string.Empty); private void onTokenChanged(OAuthToken token) => config.Set(OsuSetting.Token, config.Get<bool>(OsuSetting.SavePassword) ? authentication.TokenString : string.Empty);
@ -75,10 +79,7 @@ namespace osu.Game.Online.API
public void Unregister(IOnlineComponent component) public void Unregister(IOnlineComponent component)
{ {
Scheduler.Add(delegate Scheduler.Add(delegate { components.Remove(component); });
{
components.Remove(component);
});
} }
public string AccessToken => authentication.RequestAccessToken(); public string AccessToken => authentication.RequestAccessToken();
@ -103,6 +104,7 @@ namespace osu.Game.Online.API
log.Add(@"Queueing a ping request"); log.Add(@"Queueing a ping request");
Queue(new ListChannelsRequest { Timeout = 5000 }); Queue(new ListChannelsRequest { Timeout = 5000 });
} }
break; break;
case APIState.Offline: case APIState.Offline:
case APIState.Connecting: case APIState.Connecting:
@ -161,18 +163,21 @@ namespace osu.Game.Online.API
continue; continue;
} }
//process the request queue. while (true)
APIRequest req;
while (queue.TryPeek(out req))
{ {
if (handleRequest(req)) APIRequest req;
lock (queue)
{ {
//we have succeeded, so let's unqueue. if (queue.Count == 0) break;
queue.TryDequeue(out req); req = queue.Dequeue();
} }
// TODO: handle failures better
handleRequest(req);
} }
Thread.Sleep(1); Thread.Sleep(50);
} }
} }
@ -205,7 +210,8 @@ namespace osu.Game.Online.API
} }
catch (WebException we) catch (WebException we)
{ {
HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode ?? (we.Status == WebExceptionStatus.UnknownError ? HttpStatusCode.NotAcceptable : HttpStatusCode.RequestTimeout); HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode
?? (we.Status == WebExceptionStatus.UnknownError ? HttpStatusCode.NotAcceptable : HttpStatusCode.RequestTimeout);
// special cases for un-typed but useful message responses. // special cases for un-typed but useful message responses.
switch (we.Message) switch (we.Message)
@ -247,6 +253,7 @@ namespace osu.Game.Online.API
} }
private APIState state; private APIState state;
public APIState State public APIState State
{ {
get { return state; } get { return state; }
@ -271,7 +278,10 @@ namespace osu.Game.Online.API
public bool IsLoggedIn => LocalUser.Value.Id > 1; public bool IsLoggedIn => LocalUser.Value.Id > 1;
public void Queue(APIRequest request) => queue.Enqueue(request); public void Queue(APIRequest request)
{
lock (queue) queue.Enqueue(request);
}
public event StateChangeDelegate OnStateChange; public event StateChangeDelegate OnStateChange;
@ -279,16 +289,17 @@ namespace osu.Game.Online.API
private void flushQueue(bool failOldRequests = true) private void flushQueue(bool failOldRequests = true)
{ {
var oldQueue = queue; lock (queue)
//flush the queue.
queue = new ConcurrentQueue<APIRequest>();
if (failOldRequests)
{ {
APIRequest req; var oldQueueRequests = queue.ToArray();
while (oldQueue.TryDequeue(out req))
req.Fail(new WebException(@"Disconnected from server")); queue.Clear();
if (failOldRequests)
{
foreach (var req in oldQueueRequests)
req.Fail(new WebException(@"Disconnected from server"));
}
} }
} }