feat(fundamentals): add KeyedLockPool for concurrent scraping synchronization and update MQTT RPC handlers
This commit is contained in:
@@ -35,15 +35,10 @@ public class FundamentalsMqttClient : ManagedMqttClient, IHostedService
|
||||
/// <inheritdoc />
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var config = new MqttConfiguration
|
||||
{
|
||||
Host = _configuration["MQTT:Host"] ?? _configuration["MQTT__Host"] ?? "localhost",
|
||||
Port = Convert.ToInt32(_configuration["MQTT:Port"] ?? _configuration["MQTT__Port"] ?? "1883"),
|
||||
ClientId = _configuration["MQTT:ClientId"] ?? "finlytic_fundamentals_" + Guid.NewGuid().ToString("N")
|
||||
};
|
||||
var config = MqttConfiguration.FromConfiguration(_configuration, "FinlyticFundamentals");
|
||||
|
||||
_logger.LogInformation("[{Channel}] [MQTT_Client] Starting Fundamentals MQTT client. Host: {Host}, ClientId: {ClientId}", "MqttChannel", config.Host, config.ClientId);
|
||||
|
||||
|
||||
await ConnectAsync(config);
|
||||
}
|
||||
|
||||
@@ -58,18 +53,19 @@ public class FundamentalsMqttClient : ManagedMqttClient, IHostedService
|
||||
protected override async Task OnConnectedAsync()
|
||||
{
|
||||
_logger.LogInformation("[{Channel}] [MQTT_Client] Connected. Subscribing to RPC request topics...", "MqttChannel");
|
||||
await SubscribeAsync("services/request/fundamentals_Get/#");
|
||||
await SubscribeAsync("services/request/events_GetAll/#");
|
||||
await SubscribeAsync("services/request/events_GetByMonth/#");
|
||||
await SubscribeAsync("services/request/fundamentals_settings_GetAll/#");
|
||||
await SubscribeAsync("services/request/fundamentals_settings_Update/#");
|
||||
await SubscribeAsync("services/request/health_Ping/#");
|
||||
await SubscribeAsync(MqttTopics.ResponseWildcard);
|
||||
await SubscribeAsync(MqttTopics.RequestFilter(MqttTopics.Channels.FundamentalsGet));
|
||||
await SubscribeAsync(MqttTopics.RequestFilter(MqttTopics.Channels.EventsGetAll));
|
||||
await SubscribeAsync(MqttTopics.RequestFilter(MqttTopics.Channels.EventsGetByMonth));
|
||||
await SubscribeAsync(MqttTopics.RequestFilter(MqttTopics.Channels.FundamentalsSettingsGetAll));
|
||||
await SubscribeAsync(MqttTopics.RequestFilter(MqttTopics.Channels.FundamentalsSettingsUpdate));
|
||||
await SubscribeAsync(MqttTopics.RequestFilter(MqttTopics.Channels.HealthPing));
|
||||
|
||||
FinlyticLogBroadcaster.OnLogPublished = async (logDto) =>
|
||||
{
|
||||
if (IsConnected && string.Equals(logDto.ServiceName, "FinlyticFundamentals", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await PublishAsync("finlytic/logs/FinlyticFundamentals", logDto);
|
||||
await PublishAsync(MqttTopics.Logs("FinlyticFundamentals"), logDto);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -84,27 +80,27 @@ public class FundamentalsMqttClient : ManagedMqttClient, IHostedService
|
||||
|
||||
var correlationId = topic.Substring(lastSlash + 1);
|
||||
|
||||
if (topic.StartsWith("services/request/fundamentals_Get", StringComparison.OrdinalIgnoreCase))
|
||||
if (topic.StartsWith(MqttTopics.RequestPrefix + MqttTopics.Channels.FundamentalsGet, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await OnFundamentalsGetAsync(payload, correlationId);
|
||||
}
|
||||
else if (topic.StartsWith("services/request/events_GetAll", StringComparison.OrdinalIgnoreCase))
|
||||
else if (topic.StartsWith(MqttTopics.RequestPrefix + MqttTopics.Channels.EventsGetAll, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await OnEventsGetAllAsync(correlationId);
|
||||
}
|
||||
else if (topic.StartsWith("services/request/events_GetByMonth", StringComparison.OrdinalIgnoreCase))
|
||||
else if (topic.StartsWith(MqttTopics.RequestPrefix + MqttTopics.Channels.EventsGetByMonth, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await OnEventsGetByMonthAsync(payload, correlationId);
|
||||
}
|
||||
else if (topic.StartsWith("services/request/fundamentals_settings_GetAll", StringComparison.OrdinalIgnoreCase))
|
||||
else if (topic.StartsWith(MqttTopics.RequestPrefix + MqttTopics.Channels.FundamentalsSettingsGetAll, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await OnSettingsGetAllAsync(correlationId);
|
||||
}
|
||||
else if (topic.StartsWith("services/request/fundamentals_settings_Update", StringComparison.OrdinalIgnoreCase))
|
||||
else if (topic.StartsWith(MqttTopics.RequestPrefix + MqttTopics.Channels.FundamentalsSettingsUpdate, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await OnSettingsUpdateAsync(payload, correlationId);
|
||||
}
|
||||
else if (topic.StartsWith("services/request/health_Ping", StringComparison.OrdinalIgnoreCase))
|
||||
else if (topic.StartsWith(MqttTopics.RequestPrefix + MqttTopics.Channels.HealthPing, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await OnHealthPingAsync(topic, correlationId);
|
||||
}
|
||||
@@ -135,7 +131,7 @@ public class FundamentalsMqttClient : ManagedMqttClient, IHostedService
|
||||
request.Isin, request.ForceRefresh.ToString(), correlationId);
|
||||
|
||||
var fundamentals = await dbService.GetFundamentalsAsync(request.Isin, request.Ticker, request.ForceRefresh);
|
||||
var responseTopic = $"services/response/fundamentals_Get/{correlationId}";
|
||||
var responseTopic = MqttTopics.ResponseTopic(MqttTopics.Channels.FundamentalsGet, correlationId);
|
||||
|
||||
await finlyticLogger.LogInfoAsync(SettingKeys.MqttChannel, "[FinlyticFundamentals] [MQTT_Client] Publishing RPC fundamentals response to '{ResponseTopic}'", responseTopic);
|
||||
await PublishAsync(responseTopic, fundamentals);
|
||||
@@ -156,7 +152,7 @@ public class FundamentalsMqttClient : ManagedMqttClient, IHostedService
|
||||
try
|
||||
{
|
||||
var events = await dbService.GetAllEventsAsync();
|
||||
var responseTopic = $"services/response/events_GetAll/{correlationId}";
|
||||
var responseTopic = MqttTopics.ResponseTopic(MqttTopics.Channels.EventsGetAll, correlationId);
|
||||
|
||||
await finlyticLogger.LogInfoAsync(SettingKeys.MqttChannel, "[FinlyticFundamentals] [MQTT_Client] Publishing events RPC response to '{ResponseTopic}'", responseTopic);
|
||||
await PublishAsync(responseTopic, events);
|
||||
@@ -183,7 +179,7 @@ public class FundamentalsMqttClient : ManagedMqttClient, IHostedService
|
||||
await finlyticLogger.LogInfoAsync(SettingKeys.MqttChannel, "[FinlyticFundamentals] [MQTT_Client] Processing RPC events_GetByMonth request for {Year}/{Month} [CorrelationId: {CorrelationId}]", request.Year, request.Month, correlationId);
|
||||
|
||||
var events = await dbService.GetEventsByMonthAsync(request.Year, request.Month);
|
||||
var responseTopic = $"services/response/events_GetByMonth/{correlationId}";
|
||||
var responseTopic = MqttTopics.ResponseTopic(MqttTopics.Channels.EventsGetByMonth, correlationId);
|
||||
|
||||
await finlyticLogger.LogInfoAsync(SettingKeys.MqttChannel, "[FinlyticFundamentals] [MQTT_Client] Publishing monthly events RPC response to '{ResponseTopic}'", responseTopic);
|
||||
await PublishAsync(responseTopic, events);
|
||||
@@ -204,7 +200,7 @@ public class FundamentalsMqttClient : ManagedMqttClient, IHostedService
|
||||
try
|
||||
{
|
||||
var settings = await settingsService.GetAllRegisteredSettingsAsync(new[] { typeof(SettingKeys) });
|
||||
var responseTopic = $"services/response/fundamentals_settings_GetAll/{correlationId}";
|
||||
var responseTopic = MqttTopics.ResponseTopic(MqttTopics.Channels.FundamentalsSettingsGetAll, correlationId);
|
||||
|
||||
await PublishAsync(responseTopic, settings);
|
||||
await finlyticLogger.LogInfoAsync(SettingKeys.MqttChannel, "[FinlyticFundamentals] [Settings_GetAll] Published {Count} settings to '{ResponseTopic}'", settings.Count, responseTopic);
|
||||
@@ -251,7 +247,7 @@ public class FundamentalsMqttClient : ManagedMqttClient, IHostedService
|
||||
}
|
||||
|
||||
var currentSettings = await settingsService.GetAllRegisteredSettingsAsync(new[] { typeof(SettingKeys) });
|
||||
var responseTopic = $"services/response/fundamentals_settings_Update/{correlationId}";
|
||||
var responseTopic = MqttTopics.ResponseTopic(MqttTopics.Channels.FundamentalsSettingsUpdate, correlationId);
|
||||
await PublishAsync(responseTopic, currentSettings);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -267,7 +263,7 @@ public class FundamentalsMqttClient : ManagedMqttClient, IHostedService
|
||||
await using var scope = _scopeFactory.CreateAsyncScope();
|
||||
var finlyticLogger = scope.ServiceProvider.GetRequiredService<IFinlyticLogger<FundamentalsMqttClient>>();
|
||||
|
||||
var respTopic = $"services/response/health_Ping/{correlationId}";
|
||||
var respTopic = MqttTopics.ResponseTopic(MqttTopics.Channels.HealthPing, correlationId);
|
||||
await PublishAsync(respTopic, new ServiceHealthResponse("FinlyticFundamentals", "Online", DateTime.UtcNow, "Connected"));
|
||||
await finlyticLogger.LogInfoAsync(SettingKeys.HealthPingChannel, "[FinlyticFundamentals] [Health_Ping] Responded to live health_Ping RPC request [CorrelationId: {CorrelationId}].", correlationId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user