Rename Vexer to Excititor

This commit is contained in:
2025-10-18 20:00:46 +03:00
parent fbd1826ef3
commit 7e1b10d3b2
263 changed files with 848 additions and 848 deletions

View File

@@ -0,0 +1,47 @@
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using StellaOps.Plugin;
namespace StellaOps.Excititor.Worker.Scheduling;
internal sealed class DefaultVexProviderRunner : IVexProviderRunner
{
private readonly IServiceProvider _serviceProvider;
private readonly PluginCatalog _pluginCatalog;
private readonly ILogger<DefaultVexProviderRunner> _logger;
public DefaultVexProviderRunner(
IServiceProvider serviceProvider,
PluginCatalog pluginCatalog,
ILogger<DefaultVexProviderRunner> logger)
{
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
_pluginCatalog = pluginCatalog ?? throw new ArgumentNullException(nameof(pluginCatalog));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public ValueTask RunAsync(string providerId, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrWhiteSpace(providerId);
using var scope = _serviceProvider.CreateScope();
var availablePlugins = _pluginCatalog.GetAvailableConnectorPlugins(scope.ServiceProvider);
var matched = availablePlugins.FirstOrDefault(plugin =>
string.Equals(plugin.Name, providerId, StringComparison.OrdinalIgnoreCase));
if (matched is null)
{
_logger.LogInformation("No connector plugin registered for provider {ProviderId}; nothing to execute.", providerId);
return ValueTask.CompletedTask;
}
_logger.LogInformation(
"Connector plugin {PluginName} ({ProviderId}) is available. Execution hooks will be added in subsequent tasks.",
matched.Name,
providerId);
return ValueTask.CompletedTask;
}
}

View File

@@ -0,0 +1,6 @@
namespace StellaOps.Excititor.Worker.Scheduling;
internal interface IVexProviderRunner
{
ValueTask RunAsync(string providerId, CancellationToken cancellationToken);
}

View File

@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StellaOps.Excititor.Worker.Options;
namespace StellaOps.Excititor.Worker.Scheduling;
internal sealed class VexWorkerHostedService : BackgroundService
{
private readonly IOptions<VexWorkerOptions> _options;
private readonly IVexProviderRunner _runner;
private readonly ILogger<VexWorkerHostedService> _logger;
private readonly TimeProvider _timeProvider;
public VexWorkerHostedService(
IOptions<VexWorkerOptions> options,
IVexProviderRunner runner,
ILogger<VexWorkerHostedService> logger,
TimeProvider timeProvider)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
_runner = runner ?? throw new ArgumentNullException(nameof(runner));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_timeProvider = timeProvider ?? throw new ArgumentNullException(nameof(timeProvider));
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var schedules = _options.Value.ResolveSchedules();
if (schedules.Count == 0)
{
_logger.LogWarning("Excititor worker has no configured provider schedules; the service will remain idle.");
await Task.CompletedTask;
return;
}
_logger.LogInformation("Excititor worker starting with {ProviderCount} provider schedule(s).", schedules.Count);
var tasks = new List<Task>(schedules.Count);
foreach (var schedule in schedules)
{
tasks.Add(RunScheduleAsync(schedule, stoppingToken));
}
await Task.WhenAll(tasks);
}
private async Task RunScheduleAsync(VexWorkerSchedule schedule, CancellationToken cancellationToken)
{
try
{
if (schedule.InitialDelay > TimeSpan.Zero)
{
_logger.LogInformation(
"Provider {ProviderId} initial delay of {InitialDelay} before first execution.",
schedule.ProviderId,
schedule.InitialDelay);
await Task.Delay(schedule.InitialDelay, cancellationToken).ConfigureAwait(false);
}
using var timer = new PeriodicTimer(schedule.Interval);
do
{
var startedAt = _timeProvider.GetUtcNow();
_logger.LogInformation(
"Provider {ProviderId} run started at {StartedAt}. Interval={Interval}.",
schedule.ProviderId,
startedAt,
schedule.Interval);
try
{
await _runner.RunAsync(schedule.ProviderId, cancellationToken).ConfigureAwait(false);
var completedAt = _timeProvider.GetUtcNow();
var elapsed = completedAt - startedAt;
_logger.LogInformation(
"Provider {ProviderId} run completed at {CompletedAt} (duration {Duration}).",
schedule.ProviderId,
completedAt,
elapsed);
}
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
_logger.LogInformation("Provider {ProviderId} run cancelled.", schedule.ProviderId);
break;
}
catch (Exception ex)
{
_logger.LogError(
ex,
"Provider {ProviderId} run failed: {Message}",
schedule.ProviderId,
ex.Message);
}
}
while (await timer.WaitForNextTickAsync(cancellationToken).ConfigureAwait(false));
}
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
_logger.LogInformation("Provider {ProviderId} schedule cancelled.", schedule.ProviderId);
}
}
}

View File

@@ -0,0 +1,3 @@
namespace StellaOps.Excititor.Worker.Scheduling;
internal sealed record VexWorkerSchedule(string ProviderId, TimeSpan Interval, TimeSpan InitialDelay);