Rename Feedser to Concelier

This commit is contained in:
master
2025-10-18 20:04:15 +03:00
parent dd66f58b00
commit 89ede53cc3
1208 changed files with 4370 additions and 4370 deletions

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Concelier.Storage.Mongo.Exporting;
/// <summary>
/// Helper for exporters to read and persist their export metadata in Mongo-backed storage.
/// </summary>
public sealed class ExportStateManager
{
private readonly IExportStateStore _store;
private readonly TimeProvider _timeProvider;
public ExportStateManager(IExportStateStore store, TimeProvider? timeProvider = null)
{
_store = store ?? throw new ArgumentNullException(nameof(store));
_timeProvider = timeProvider ?? TimeProvider.System;
}
public Task<ExportStateRecord?> GetAsync(string exporterId, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(exporterId);
return _store.FindAsync(exporterId, cancellationToken);
}
public async Task<ExportStateRecord> StoreFullExportAsync(
string exporterId,
string exportId,
string exportDigest,
string? cursor,
string? targetRepository,
string exporterVersion,
bool resetBaseline,
IReadOnlyList<ExportFileRecord> manifest,
CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(exporterId);
ArgumentException.ThrowIfNullOrEmpty(exportId);
ArgumentException.ThrowIfNullOrEmpty(exportDigest);
ArgumentException.ThrowIfNullOrEmpty(exporterVersion);
manifest ??= Array.Empty<ExportFileRecord>();
var existing = await _store.FindAsync(exporterId, cancellationToken).ConfigureAwait(false);
var now = _timeProvider.GetUtcNow();
if (existing is null)
{
var resolvedRepository = string.IsNullOrWhiteSpace(targetRepository) ? null : targetRepository;
return await _store.UpsertAsync(
new ExportStateRecord(
exporterId,
BaseExportId: exportId,
BaseDigest: exportDigest,
LastFullDigest: exportDigest,
LastDeltaDigest: null,
ExportCursor: cursor ?? exportDigest,
TargetRepository: resolvedRepository,
ExporterVersion: exporterVersion,
UpdatedAt: now,
Files: manifest),
cancellationToken).ConfigureAwait(false);
}
var repositorySpecified = !string.IsNullOrWhiteSpace(targetRepository);
var resolvedRepo = repositorySpecified ? targetRepository : existing.TargetRepository;
var repositoryChanged = repositorySpecified
&& !string.Equals(existing.TargetRepository, targetRepository, StringComparison.Ordinal);
var shouldResetBaseline =
resetBaseline
|| string.IsNullOrWhiteSpace(existing.BaseExportId)
|| string.IsNullOrWhiteSpace(existing.BaseDigest)
|| repositoryChanged;
var updatedRecord = shouldResetBaseline
? existing with
{
BaseExportId = exportId,
BaseDigest = exportDigest,
LastFullDigest = exportDigest,
LastDeltaDigest = null,
ExportCursor = cursor ?? exportDigest,
TargetRepository = resolvedRepo,
ExporterVersion = exporterVersion,
UpdatedAt = now,
Files = manifest,
}
: existing with
{
LastFullDigest = exportDigest,
LastDeltaDigest = null,
ExportCursor = cursor ?? existing.ExportCursor,
TargetRepository = resolvedRepo,
ExporterVersion = exporterVersion,
UpdatedAt = now,
Files = manifest,
};
return await _store.UpsertAsync(updatedRecord, cancellationToken).ConfigureAwait(false);
}
public async Task<ExportStateRecord> StoreDeltaExportAsync(
string exporterId,
string deltaDigest,
string? cursor,
string exporterVersion,
IReadOnlyList<ExportFileRecord> manifest,
CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(exporterId);
ArgumentException.ThrowIfNullOrEmpty(deltaDigest);
ArgumentException.ThrowIfNullOrEmpty(exporterVersion);
manifest ??= Array.Empty<ExportFileRecord>();
var existing = await _store.FindAsync(exporterId, cancellationToken).ConfigureAwait(false);
if (existing is null)
{
throw new InvalidOperationException($"Full export state missing for '{exporterId}'.");
}
var now = _timeProvider.GetUtcNow();
var record = existing with
{
LastDeltaDigest = deltaDigest,
ExportCursor = cursor ?? existing.ExportCursor,
ExporterVersion = exporterVersion,
UpdatedAt = now,
Files = manifest,
};
return await _store.UpsertAsync(record, cancellationToken).ConfigureAwait(false);
}
}