some fixes for server, perhaps

This commit is contained in:
rootdarkarchon
2022-12-27 21:59:41 +01:00
parent b8c10c4298
commit 3ba37515ab
3 changed files with 82 additions and 46 deletions

View File

@@ -18,6 +18,8 @@ using MareSynchronosShared.Utils;
using MareSynchronosServer.Identity; using MareSynchronosServer.Identity;
using MareSynchronosShared.Services; using MareSynchronosShared.Services;
using Prometheus; using Prometheus;
using Microsoft.Extensions.Options;
using Grpc.Net.ClientFactory;
namespace MareSynchronosServer; namespace MareSynchronosServer;
@@ -207,7 +209,7 @@ public class Startup
}; };
}); });
services.AddGrpcClient<ConfigurationService.ConfigurationServiceClient>(c => services.AddGrpcClient<ConfigurationService.ConfigurationServiceClient>("MainServer", c =>
{ {
c.Address = new Uri(mareConfig.GetValue<string>(nameof(ServerConfiguration.MainServerGrpcAddress))); c.Address = new Uri(mareConfig.GetValue<string>(nameof(ServerConfiguration.MainServerGrpcAddress)));
}).ConfigureChannel(c => }).ConfigureChannel(c =>
@@ -221,8 +223,16 @@ public class Startup
services.AddSingleton<IClientIdentificationService, GrpcClientIdentificationService>(); services.AddSingleton<IClientIdentificationService, GrpcClientIdentificationService>();
services.AddHostedService(p => p.GetService<IClientIdentificationService>()); services.AddHostedService(p => p.GetService<IClientIdentificationService>());
services.AddSingleton<IConfigurationService<ServerConfiguration>, MareConfigurationServiceClient<ServerConfiguration>>(); services.AddSingleton<IConfigurationService<ServerConfiguration>>(c => new MareConfigurationServiceClient<ServerConfiguration>(
services.AddSingleton<IConfigurationService<MareConfigurationAuthBase>, MareConfigurationServiceClient<MareConfigurationAuthBase>>(); c.GetService<ILogger<MareConfigurationServiceClient<ServerConfiguration>>>(),
c.GetService<IOptions<ServerConfiguration>>(),
c.GetService<GrpcClientFactory>(),
"MainServer"));
services.AddSingleton<IConfigurationService<MareConfigurationAuthBase>>(c => new MareConfigurationServiceClient<MareConfigurationAuthBase>(
c.GetService<ILogger<MareConfigurationServiceClient<MareConfigurationAuthBase>>>(),
c.GetService<IOptions<MareConfigurationAuthBase>>(),
c.GetService<GrpcClientFactory>(),
"MainServer"));
} }
else else
{ {

View File

@@ -7,6 +7,9 @@ using MareSynchronosShared.Utils;
using Grpc.Net.Client.Configuration; using Grpc.Net.Client.Configuration;
using MareSynchronosShared.Protos; using MareSynchronosShared.Protos;
using MareSynchronosShared.Services; using MareSynchronosShared.Services;
using Grpc.Net.ClientFactory;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.DependencyInjection;
namespace MareSynchronosServices; namespace MareSynchronosServices;
@@ -33,7 +36,7 @@ public class Startup
}, Configuration.GetValue(nameof(MareConfigurationBase.DbContextPoolSize), 1024)); }, Configuration.GetValue(nameof(MareConfigurationBase.DbContextPoolSize), 1024));
services.AddSingleton(m => new MareMetrics(m.GetService<ILogger<MareMetrics>>(), new List<string> { }, services.AddSingleton(m => new MareMetrics(m.GetService<ILogger<MareMetrics>>(), new List<string> { },
new List<string> {})); new List<string> { }));
var noRetryConfig = new MethodConfig var noRetryConfig = new MethodConfig
{ {
@@ -53,7 +56,7 @@ public class Startup
}; };
}); });
services.AddGrpcClient<ConfigurationService.ConfigurationServiceClient>(c => services.AddGrpcClient<ConfigurationService.ConfigurationServiceClient>("MainServer", c =>
{ {
c.Address = new Uri(mareConfig.GetValue<string>(nameof(ServicesConfiguration.MainServerGrpcAddress))); c.Address = new Uri(mareConfig.GetValue<string>(nameof(ServicesConfiguration.MainServerGrpcAddress)));
}).ConfigureChannel(c => }).ConfigureChannel(c =>
@@ -72,8 +75,16 @@ public class Startup
services.AddSingleton<DiscordBotServices>(); services.AddSingleton<DiscordBotServices>();
services.AddHostedService<DiscordBot>(); services.AddHostedService<DiscordBot>();
services.AddSingleton<IConfigurationService<ServicesConfiguration>, MareConfigurationServiceServer<ServicesConfiguration>>(); services.AddSingleton<IConfigurationService<ServicesConfiguration>, MareConfigurationServiceServer<ServicesConfiguration>>();
services.AddSingleton<IConfigurationService<ServerConfiguration>, MareConfigurationServiceClient<ServerConfiguration>>(); services.AddSingleton<IConfigurationService<ServerConfiguration>>(c => new MareConfigurationServiceClient<ServerConfiguration>(
services.AddSingleton<IConfigurationService<MareConfigurationAuthBase>, MareConfigurationServiceClient<MareConfigurationAuthBase>>(); c.GetService<ILogger<MareConfigurationServiceClient<ServerConfiguration>>>(),
c.GetService<IOptions<ServerConfiguration>>(),
c.GetService<GrpcClientFactory>(),
"MainServer"));
services.AddSingleton<IConfigurationService<MareConfigurationAuthBase>>(c => new MareConfigurationServiceClient<MareConfigurationAuthBase>(
c.GetService<ILogger<MareConfigurationServiceClient<MareConfigurationAuthBase>>>(),
c.GetService<IOptions<MareConfigurationAuthBase>>(),
c.GetService<GrpcClientFactory>(),
"MainServer"));
} }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

View File

@@ -18,20 +18,16 @@ public class MareConfigurationServiceClient<T> : IConfigurationService<T> where
private readonly T _config; private readonly T _config;
private readonly ConcurrentDictionary<string, RemoteCachedEntry> _cachedRemoteProperties = new(StringComparer.Ordinal); private readonly ConcurrentDictionary<string, RemoteCachedEntry> _cachedRemoteProperties = new(StringComparer.Ordinal);
private readonly ILogger<MareConfigurationServiceClient<T>> _logger; private readonly ILogger<MareConfigurationServiceClient<T>> _logger;
private readonly ConfigurationServiceClient _configurationServiceClient; private readonly GrpcClientFactory _grpcClientFactory;
private readonly string _grpcClientName;
public MareConfigurationServiceClient(ILogger<MareConfigurationServiceClient<T>> logger, IOptions<T> config, ConfigurationServiceClient configurationServiceClient) private static SemaphoreSlim _readLock = new(1);
{
_config = config.Value;
_logger = logger;
_configurationServiceClient = configurationServiceClient;
}
public MareConfigurationServiceClient(ILogger<MareConfigurationServiceClient<T>> logger, IOptions<T> config, GrpcClientFactory grpcClientFactory, string grpcClientName) public MareConfigurationServiceClient(ILogger<MareConfigurationServiceClient<T>> logger, IOptions<T> config, GrpcClientFactory grpcClientFactory, string grpcClientName)
{ {
_config = config.Value; _config = config.Value;
_logger = logger; _logger = logger;
_configurationServiceClient = grpcClientFactory.CreateClient<ConfigurationServiceClient>(grpcClientName); _grpcClientFactory = grpcClientFactory;
_grpcClientName = grpcClientName;
} }
public bool IsMain => false; public bool IsMain => false;
@@ -44,14 +40,13 @@ public class MareConfigurationServiceClient<T> : IConfigurationService<T> where
bool isRemote = prop.GetCustomAttributes(typeof(RemoteConfigurationAttribute), inherit: true).Any(); bool isRemote = prop.GetCustomAttributes(typeof(RemoteConfigurationAttribute), inherit: true).Any();
if (isRemote) if (isRemote)
{ {
bool isCurrent = false; _readLock.Wait();
if (_cachedRemoteProperties.TryGetValue(key, out var existingEntry) && existingEntry.Inserted > DateTime.Now - TimeSpan.FromMinutes(30)) if (_cachedRemoteProperties.TryGetValue(key, out var existingEntry) && existingEntry.Inserted > DateTime.Now - TimeSpan.FromMinutes(60))
{ {
isCurrent = true; _readLock.Release();
return (T1)_cachedRemoteProperties[key].Value;
} }
if (!isCurrent)
{
try try
{ {
var result = GetValueFromGrpc(key, defaultValue, prop.PropertyType); var result = GetValueFromGrpc(key, defaultValue, prop.PropertyType);
@@ -72,6 +67,9 @@ public class MareConfigurationServiceClient<T> : IConfigurationService<T> where
return defaultValue; return defaultValue;
} }
} }
finally
{
_readLock.Release();
} }
} }
@@ -85,12 +83,14 @@ public class MareConfigurationServiceClient<T> : IConfigurationService<T> where
try try
{ {
_logger.LogInformation("Getting {key} from Grpc", key); _logger.LogInformation("Getting {key} from Grpc", key);
var response = _configurationServiceClient.GetConfigurationEntry(new KeyMessage { Key = key, Default = Convert.ToString(defaultValue, CultureInfo.InvariantCulture) }); var configClient = _grpcClientFactory.CreateClient<ConfigurationServiceClient>(_grpcClientName);
var response = configClient.GetConfigurationEntry(new KeyMessage { Key = key, Default = Convert.ToString(defaultValue, CultureInfo.InvariantCulture) });
_logger.LogInformation("Grpc Response for {key} = {value}", key, response.Value); _logger.LogInformation("Grpc Response for {key} = {value}", key, response.Value);
return new RemoteCachedEntry(JsonSerializer.Deserialize(response.Value, t), DateTime.Now); return new RemoteCachedEntry(JsonSerializer.Deserialize(response.Value, t), DateTime.Now);
} }
catch catch (Exception ex)
{ {
_logger.LogWarning(ex, "Failure Getting Cached Entry");
return null; return null;
} }
} }
@@ -103,23 +103,38 @@ public class MareConfigurationServiceClient<T> : IConfigurationService<T> where
bool isRemote = prop.GetCustomAttributes(typeof(RemoteConfigurationAttribute), inherit: true).Any(); bool isRemote = prop.GetCustomAttributes(typeof(RemoteConfigurationAttribute), inherit: true).Any();
if (isRemote) if (isRemote)
{ {
bool isCurrent = false; _readLock.Wait();
if (_cachedRemoteProperties.TryGetValue(key, out var existingEntry) && existingEntry.Inserted > DateTime.Now - TimeSpan.FromMinutes(30)) if (_cachedRemoteProperties.TryGetValue(key, out var existingEntry) && existingEntry.Inserted > DateTime.Now - TimeSpan.FromMinutes(60))
{ {
isCurrent = true; _readLock.Release();
return (T1)_cachedRemoteProperties[key].Value;
} }
if (!isCurrent) try
{ {
var result = GetValueFromGrpc(key, null, prop.PropertyType); var result = GetValueFromGrpc(key, null, prop.PropertyType);
if (result == null) throw new KeyNotFoundException(key); if (result == null) throw new KeyNotFoundException(key);
_cachedRemoteProperties[key] = result; _cachedRemoteProperties[key] = result;
}
if (!_cachedRemoteProperties.ContainsKey(key)) throw new KeyNotFoundException(key);
return (T1)_cachedRemoteProperties[key].Value; return (T1)_cachedRemoteProperties[key].Value;
} }
catch (Exception ex)
{
if (existingEntry != null)
{
_logger.LogWarning(ex, "Could not get value for {key} from Grpc, returning existing", key);
return (T1)existingEntry.Value;
}
else
{
_logger.LogWarning(ex, "Could not get value for {key} from Grpc, throwing exception", key);
throw new KeyNotFoundException(key);
}
}
finally
{
_readLock.Release();
}
}
var value = prop.GetValue(_config); var value = prop.GetValue(_config);
return (T1)value; return (T1)value;