Resolve Concelier/Excititor merge conflicts

This commit is contained in:
master
2025-10-20 14:19:25 +03:00
2687 changed files with 212646 additions and 85913 deletions

View File

@@ -0,0 +1,128 @@
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using System;
using System.Threading;
using System.Threading.Tasks;
using StellaOps.Authority.Storage.Mongo.Options;
namespace StellaOps.Authority.Storage.Mongo.Sessions;
public interface IAuthorityMongoSessionAccessor : IAsyncDisposable
{
ValueTask<IClientSessionHandle> GetSessionAsync(CancellationToken cancellationToken = default);
}
internal sealed class AuthorityMongoSessionAccessor : IAuthorityMongoSessionAccessor
{
private readonly IMongoClient client;
private readonly AuthorityMongoOptions options;
private readonly object gate = new();
private Task<IClientSessionHandle>? sessionTask;
private IClientSessionHandle? session;
private bool disposed;
public AuthorityMongoSessionAccessor(
IMongoClient client,
IOptions<AuthorityMongoOptions> options)
{
this.client = client ?? throw new ArgumentNullException(nameof(client));
this.options = options?.Value ?? throw new ArgumentNullException(nameof(options));
}
public async ValueTask<IClientSessionHandle> GetSessionAsync(CancellationToken cancellationToken = default)
{
ObjectDisposedException.ThrowIf(disposed, this);
var existing = Volatile.Read(ref session);
if (existing is not null)
{
return existing;
}
Task<IClientSessionHandle> startTask;
lock (gate)
{
if (session is { } cached)
{
return cached;
}
sessionTask ??= StartSessionInternalAsync(cancellationToken);
startTask = sessionTask;
}
try
{
var handle = await startTask.WaitAsync(cancellationToken).ConfigureAwait(false);
if (session is null)
{
lock (gate)
{
if (session is null)
{
session = handle;
sessionTask = Task.FromResult(handle);
}
}
}
return handle;
}
catch
{
lock (gate)
{
if (ReferenceEquals(sessionTask, startTask))
{
sessionTask = null;
}
}
throw;
}
}
private async Task<IClientSessionHandle> StartSessionInternalAsync(CancellationToken cancellationToken)
{
var sessionOptions = new ClientSessionOptions
{
CausalConsistency = true,
DefaultTransactionOptions = new TransactionOptions(
readPreference: ReadPreference.Primary,
readConcern: ReadConcern.Majority,
writeConcern: WriteConcern.WMajority.With(wTimeout: options.CommandTimeout))
};
var handle = await client.StartSessionAsync(sessionOptions, cancellationToken).ConfigureAwait(false);
return handle;
}
public ValueTask DisposeAsync()
{
if (disposed)
{
return ValueTask.CompletedTask;
}
disposed = true;
IClientSessionHandle? handle;
lock (gate)
{
handle = session;
session = null;
sessionTask = null;
}
if (handle is not null)
{
handle.Dispose();
}
GC.SuppressFinalize(this);
return ValueTask.CompletedTask;
}
}