feat(localdb): telemetry meters + ISyncStatus

Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
This commit is contained in:
Joseph Doherty
2026-07-18 00:03:39 -04:00
parent 8befebd476
commit be4ca76f5f
9 changed files with 765 additions and 8 deletions
@@ -18,16 +18,24 @@ public sealed class LocalDbSyncService : LocalDbSync.LocalDbSyncBase
private readonly ReplicationOptions _options;
private readonly ILoggerFactory _loggerFactory;
private readonly ILogger<LocalDbSyncService> _logger;
private readonly LocalDbMetrics? _metrics;
private readonly SyncStatus? _status;
// 0 = idle, 1 = a stream is active. Interlocked-guarded across concurrent calls (singleton service).
private int _active;
public LocalDbSyncService(ILocalDb db, IOptions<ReplicationOptions> options, ILoggerFactory loggerFactory)
// status is taken as the public ISyncStatus (SyncStatus is internal and cannot appear in a
// public signature); DI always supplies the concrete SyncStatus this cast recovers.
public LocalDbSyncService(
ILocalDb db, IOptions<ReplicationOptions> options, ILoggerFactory loggerFactory,
LocalDbMetrics? metrics = null, ISyncStatus? status = null)
{
_db = SyncSessionFactory.RequireSqlite(db, nameof(LocalDbSyncService));
_options = options.Value;
_loggerFactory = loggerFactory;
_logger = loggerFactory.CreateLogger<LocalDbSyncService>();
_metrics = metrics;
_status = status as SyncStatus;
}
public override async Task Sync(
@@ -46,13 +54,15 @@ public sealed class LocalDbSyncService : LocalDbSync.LocalDbSyncBase
// handler has exited.
using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(context.CancellationToken);
var (duplex, readerTask) = GrpcSyncDuplex.Create(requestStream, responseStream, linkedCts.Token);
var session = SyncSessionFactory.Create(_db, _options, _loggerFactory);
var session = SyncSessionFactory.Create(_db, _options, _loggerFactory, _metrics, _status);
_status?.SetConnected(true);
try
{
await session.RunAsync(duplex, linkedCts.Token);
}
finally
{
_status?.SetConnected(false);
linkedCts.Cancel();
try
{