chore: 提出 AppRouter 模块,以备后面共享使用

oneRain 2019-08-15 15:11:38 +08:00
parent 991446940a
commit fc4ff081f7
5 changed files with 52 additions and 79 deletions

View File

@ -7,36 +7,36 @@ using Newtonsoft.Json;
namespace LeanCloud.Storage.Internal {
public class AppRouterController {
private AppRouterState currentState;
private readonly ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
public AppRouterState Get(string appId) {
private readonly SemaphoreSlim locker = new SemaphoreSlim(1);
public async Task<AppRouterState> Get(string appId) {
if (string.IsNullOrEmpty(appId)) {
throw new ArgumentNullException(nameof(appId));
}
try {
locker.EnterUpgradeableReadLock();
if (currentState != null && !currentState.IsExpired) {
return currentState;
}
// 从 AppRouter 获取服务器地址,只触发,不等待
QueryAsync(appId).ContinueWith(t => {
if (t.IsFaulted) {
if (currentState != null && !currentState.IsExpired) {
return currentState;
}
} else {
locker.EnterWriteLock();
currentState = t.Result;
currentState.Source = "router";
locker.ExitWriteLock();
await locker.WaitAsync();
try {
if (currentState == null) {
try {
currentState = await QueryAsync(appId);
} catch (Exception) {
currentState = AppRouterState.GetFallbackServers(appId);
}
});
return AppRouterState.GetFallbackServers(appId);
}
return currentState;
} finally {
locker.ExitUpgradeableReadLock();
locker.Release();
}
}
public async Task<AppRouterState> QueryAsync(string appId) {
Console.WriteLine("QueryAsync");
string url = string.Format("https://app-router.leancloud.cn/2/route?appId={0}", appId);
HttpClient client = new HttpClient();
@ -52,13 +52,13 @@ namespace LeanCloud.Storage.Internal {
string content = await response.Content.ReadAsStringAsync();
response.Dispose();
return JsonConvert.DeserializeObject<AppRouterState>(content);
AppRouterState state = JsonConvert.DeserializeObject<AppRouterState>(content);
state.Source = "router";
return state;
}
public void Clear() {
locker.EnterWriteLock();
currentState = null;
locker.ExitWriteLock();
}
}
}

View File

@ -0,0 +1,16 @@
using NUnit.Framework;
using System.Threading.Tasks;
using LeanCloud.Storage.Internal;
namespace LeanCloudTests {
public class AppRouterTest {
[Test]
public async Task GetServers() {
var appRouter = new AppRouterController();
for (int i = 0; i < 1000; i++) {
var state = await appRouter.Get("BMYV4RKSTwo8WSqt8q9ezcWF-gzGzoHsz");
TestContext.Out.WriteLine(state.ApiServer);
}
}
}
}

View File

@ -16,5 +16,6 @@
<ItemGroup>
<ProjectReference Include="..\Storage\Storage.csproj" />
<ProjectReference Include="..\..\AppRouter\AppRouter\AppRouter.csproj" />
</ItemGroup>
</Project>

View File

@ -15,6 +15,12 @@ namespace LeanCloud.Storage.Internal {
return str;
}
public static Task<string> SerializeAsync(object obj) {
return Task.Run(() => {
return JsonConvert.SerializeObject(obj);
});
}
public static async Task<T> DeserializeObjectAsync<T>(string str, params JsonConverter[] converters) {
T obj = default;
await Task.Run(() => {
@ -22,5 +28,11 @@ namespace LeanCloud.Storage.Internal {
});
return obj;
}
public static Task<T> DeserializeAsync<T>(string str, params JsonConverter[] converts) {
return Task.Run(() => {
return JsonConvert.DeserializeObject<T>(str, converts);
});
}
}
}

View File

@ -30,43 +30,6 @@ namespace LeanCloud {
/// Represents the configuration of the LeanCloud SDK.
/// </summary>
public struct Configuration {
/// <summary>
/// 与 SDK 通讯的云端节点
/// </summary>
public enum AVRegion {
/// <summary>
/// 默认值LeanCloud 华北节点,同 Public_North_China
/// </summary>
[Obsolete("please use Configuration.AVRegion.Public_North_China")]
Public_CN = 0,
/// <summary>
/// 默认值,华北公有云节点,同 Public_CN
/// </summary>
Public_North_China = 0,
/// <summary>
/// LeanCloud 北美区公有云节点,同 Public_North_America
/// </summary>
[Obsolete("please use Configuration.AVRegion.Public_North_America")]
Public_US = 1,
/// <summary>
/// LeanCloud 北美区公有云节点,同 Public_US
/// </summary>
Public_North_America = 1,
/// <summary>
/// 华东公有云节点,同 Public_East_China
/// </summary>
[Obsolete("please use Configuration.AVRegion.Public_East_China")]
Vendor_Tencent = 2,
/// <summary>
/// 华东公有云节点,同 Vendor_Tencent
/// </summary>
Public_East_China = 2,
}
/// <summary>
/// In the event that you would like to use the LeanCloud SDK
/// from a completely portable project, with no platform-specific library required,
@ -100,17 +63,6 @@ namespace LeanCloud {
/// </summary>
public string ApplicationId { get; set; }
/// <summary>
/// LeanCloud C# SDK 支持的服务节点,目前支持华北,华东和北美公有云节点和私有节点,以及专属节点
/// </summary>
public AVRegion Region { get; set; }
internal int RegionValue {
get {
return (int)Region;
}
}
/// <summary>
/// The LeanCloud application key for your app.
/// </summary>
@ -255,13 +207,6 @@ namespace LeanCloud {
internal static void Config(Configuration configuration) {
lock (mutex) {
var nodeHash = configuration.ApplicationId.Split('-');
if (nodeHash.Length > 1) {
if (nodeHash[1].Trim() == "9Nh9j0Va") {
configuration.Region = Configuration.AVRegion.Public_East_China;
}
}
CurrentConfiguration = configuration;
}
}
@ -280,11 +225,10 @@ namespace LeanCloud {
Initialize(configuration);
}
public static void Switch(string applicationId, string applicationKey, Configuration.AVRegion region = Configuration.AVRegion.Public_North_China) {
public static void Switch(string applicationId, string applicationKey) {
var configuration = new Configuration {
ApplicationId = applicationId,
ApplicationKey = applicationKey,
Region = region
ApplicationKey = applicationKey
};
Switch(configuration);
}