Harden Surreal migration with retry/coverage fixes and XML docs cleanup
All checks were successful
NuGet Package Publish / nuget (push) Successful in 1m17s
All checks were successful
NuGet Package Publish / nuget (push) Successful in 1m17s
This commit is contained in:
@@ -61,6 +61,15 @@ public abstract class SurrealDocumentStore<TContext> : IDocumentStore, ISurrealC
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SurrealDocumentStore{TContext}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="context">The application context used by the concrete store.</param>
|
||||
/// <param name="surrealEmbeddedClient">The embedded Surreal client provider.</param>
|
||||
/// <param name="schemaInitializer">The Surreal schema initializer.</param>
|
||||
/// <param name="configProvider">The peer node configuration provider.</param>
|
||||
/// <param name="vectorClockService">The vector clock service used for local oplog state.</param>
|
||||
/// <param name="conflictResolver">Optional conflict resolver; defaults to last-write-wins.</param>
|
||||
/// <param name="checkpointPersistence">Optional CDC checkpoint persistence component.</param>
|
||||
/// <param name="cdcPollingOptions">Optional CDC polling options.</param>
|
||||
/// <param name="logger">Optional logger instance.</param>
|
||||
protected SurrealDocumentStore(
|
||||
TContext context,
|
||||
ICBDDCSurrealEmbeddedClient surrealEmbeddedClient,
|
||||
@@ -128,21 +137,28 @@ public abstract class SurrealDocumentStore<TContext> : IDocumentStore, ISurrealC
|
||||
{
|
||||
private readonly ILogger _inner;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ForwardingLogger" /> class.
|
||||
/// </summary>
|
||||
/// <param name="inner">The logger instance to forward calls to.</param>
|
||||
public ForwardingLogger(ILogger inner)
|
||||
{
|
||||
_inner = inner;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IDisposable? BeginScope<TState>(TState state) where TState : notnull
|
||||
{
|
||||
return _inner.BeginScope(state);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsEnabled(LogLevel logLevel)
|
||||
{
|
||||
return _inner.IsEnabled(logLevel);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Log<TState>(
|
||||
LogLevel logLevel,
|
||||
EventId eventId,
|
||||
@@ -191,6 +207,7 @@ public abstract class SurrealDocumentStore<TContext> : IDocumentStore, ISurrealC
|
||||
/// <param name="collectionName">Logical collection name used by oplog and metadata records.</param>
|
||||
/// <param name="collection">Watchable change source.</param>
|
||||
/// <param name="keySelector">Function used to resolve the entity key.</param>
|
||||
/// <param name="subscribeForInMemoryEvents">Whether to subscribe to in-memory collection events.</param>
|
||||
protected void WatchCollection<TEntity>(
|
||||
string collectionName,
|
||||
ISurrealWatchableCollection<TEntity> collection,
|
||||
@@ -220,6 +237,12 @@ public abstract class SurrealDocumentStore<TContext> : IDocumentStore, ISurrealC
|
||||
private readonly Func<TEntity, string> _keySelector;
|
||||
private readonly SurrealDocumentStore<TContext> _store;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CdcObserver{TEntity}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="collectionName">The logical collection name.</param>
|
||||
/// <param name="keySelector">The key selector for observed entities.</param>
|
||||
/// <param name="store">The owning document store.</param>
|
||||
public CdcObserver(
|
||||
string collectionName,
|
||||
Func<TEntity, string> keySelector,
|
||||
@@ -230,6 +253,7 @@ public abstract class SurrealDocumentStore<TContext> : IDocumentStore, ISurrealC
|
||||
_store = store;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnNext(SurrealCollectionChange<TEntity> changeEvent)
|
||||
{
|
||||
if (_store.IsCdcPollingWorkerActiveForCollection(_collectionName)) return;
|
||||
@@ -267,10 +291,12 @@ public abstract class SurrealDocumentStore<TContext> : IDocumentStore, ISurrealC
|
||||
.GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnError(Exception error)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnCompleted()
|
||||
{
|
||||
}
|
||||
@@ -760,22 +786,58 @@ public abstract class SurrealDocumentStore<TContext> : IDocumentStore, ISurrealC
|
||||
|
||||
#region Abstract Methods - Implemented by subclass
|
||||
|
||||
/// <summary>
|
||||
/// Applies JSON content to a single entity in the backing store.
|
||||
/// </summary>
|
||||
/// <param name="collection">The collection name.</param>
|
||||
/// <param name="key">The document key.</param>
|
||||
/// <param name="content">The JSON payload to persist.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
protected abstract Task ApplyContentToEntityAsync(
|
||||
string collection, string key, JsonElement content, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Applies JSON content to multiple entities in the backing store.
|
||||
/// </summary>
|
||||
/// <param name="documents">The documents to persist.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
protected abstract Task ApplyContentToEntitiesBatchAsync(
|
||||
IEnumerable<(string Collection, string Key, JsonElement Content)> documents,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a single entity as JSON content.
|
||||
/// </summary>
|
||||
/// <param name="collection">The collection name.</param>
|
||||
/// <param name="key">The document key.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>The JSON content when found; otherwise <see langword="null" />.</returns>
|
||||
protected abstract Task<JsonElement?> GetEntityAsJsonAsync(
|
||||
string collection, string key, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a single entity from the backing store.
|
||||
/// </summary>
|
||||
/// <param name="collection">The collection name.</param>
|
||||
/// <param name="key">The document key.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
protected abstract Task RemoveEntityAsync(
|
||||
string collection, string key, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Removes multiple entities from the backing store.
|
||||
/// </summary>
|
||||
/// <param name="documents">The documents to remove.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
protected abstract Task RemoveEntitiesBatchAsync(
|
||||
IEnumerable<(string Collection, string Key)> documents, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all entities from a collection as JSON content.
|
||||
/// </summary>
|
||||
/// <param name="collection">The collection name.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>A sequence of key/content pairs.</returns>
|
||||
protected abstract Task<IEnumerable<(string Key, JsonElement Content)>> GetAllEntitiesAsJsonAsync(
|
||||
string collection, CancellationToken cancellationToken);
|
||||
|
||||
@@ -1055,6 +1117,12 @@ public abstract class SurrealDocumentStore<TContext> : IDocumentStore, ISurrealC
|
||||
/// <summary>
|
||||
/// Handles a local collection change and records oplog/metadata when not suppressed.
|
||||
/// </summary>
|
||||
/// <param name="collection">The collection name.</param>
|
||||
/// <param name="key">The document key.</param>
|
||||
/// <param name="operationType">The detected operation type.</param>
|
||||
/// <param name="content">Optional JSON content for non-delete operations.</param>
|
||||
/// <param name="pendingCursorCheckpoint">Optional pending cursor checkpoint to persist.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
protected async Task OnLocalChangeDetectedAsync(
|
||||
string collection,
|
||||
string key,
|
||||
@@ -1315,11 +1383,16 @@ public abstract class SurrealDocumentStore<TContext> : IDocumentStore, ISurrealC
|
||||
private readonly SemaphoreSlim _guard;
|
||||
private int _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RemoteSyncScope" /> class.
|
||||
/// </summary>
|
||||
/// <param name="guard">The guard semaphore to release on dispose.</param>
|
||||
public RemoteSyncScope(SemaphoreSlim guard)
|
||||
{
|
||||
_guard = guard;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
if (Interlocked.Exchange(ref _disposed, 1) == 1) return;
|
||||
|
||||
Reference in New Issue
Block a user