diff --git a/FoundationDB.Client/Fdb.Bulk.cs b/FoundationDB.Client/Fdb.Bulk.cs index 5eb5585a2..3f05044c3 100644 --- a/FoundationDB.Client/Fdb.Bulk.cs +++ b/FoundationDB.Client/Fdb.Bulk.cs @@ -446,7 +446,7 @@ async Task CommitBatch() if (bodyAsync != null) { - await bodyAsync(item, trans); + await bodyAsync(item, trans).ConfigureAwait(false); } else { @@ -771,7 +771,7 @@ async Task CommitBatch() chunk.CopyTo(offset, batch, 0, batch.Length); if (bodyAsync != null) { - await bodyAsync(batch, trans); + await bodyAsync(batch, trans).ConfigureAwait(false); } else { @@ -800,7 +800,7 @@ async Task CommitBatch() chunk.CopyTo(offset, batch, 0, batch.Length); if (bodyAsync != null) { - await bodyAsync(batch, trans); + await bodyAsync(batch, trans).ConfigureAwait(false); } else { @@ -1218,7 +1218,7 @@ CancellationToken ct var sw = Stopwatch.StartNew(); if (bodyAsyncWithContextAndState != null) { - localValue = await bodyAsyncWithContextAndState(items, ctx, localValue); + localValue = await bodyAsyncWithContextAndState(items, ctx, localValue).ConfigureAwait(false); } else if (bodyWithContextAndState != null) { @@ -1226,7 +1226,7 @@ CancellationToken ct } else if (bodyAsyncWithContext != null) { - await bodyAsyncWithContext(items, ctx); + await bodyAsyncWithContext(items, ctx).ConfigureAwait(false); } else { @@ -1280,7 +1280,7 @@ CancellationToken ct } else { // the error may be retry-able... - await trans.OnErrorAsync(error.Code); + await trans.OnErrorAsync(error.Code).ConfigureAwait(false); ctx.GenerationTimer.Restart(); ctx.Generation++; //REVIEW: magical number! @@ -1412,7 +1412,7 @@ public static async Task ExportAsync(IFdbDatabase db, KeySelector begin, K using (var tr = db.BeginReadOnlyTransaction(ct)) { - await reset(tr); + await reset(tr).ConfigureAwait(false); //TODO: make options configurable! var options = new FdbRangeOptions @@ -1426,7 +1426,7 @@ public static async Task ExportAsync(IFdbDatabase db, KeySelector begin, K long waitForFetch = 0; // read the first batch - var page = await FetchNextBatchAsync(tr, begin, end, options, reset); + var page = await FetchNextBatchAsync(tr, begin, end, options, reset).ConfigureAwait(false); ++waitForFetch; while (page.HasMore) @@ -1438,20 +1438,20 @@ public static async Task ExportAsync(IFdbDatabase db, KeySelector begin, K if (page.Count > 0) { ct.ThrowIfCancellationRequested(); - await handler(page.Items, count, ct); + await handler(page.Items, count, ct).ConfigureAwait(false); ++chunks; count += page.Count; } if (next.Status != TaskStatus.RanToCompletion) ++waitForFetch; - page = await next; + page = await next.ConfigureAwait(false); } // process the last page, if any if (page.Count > 0) { ct.ThrowIfCancellationRequested(); - await handler(page.Items, count, ct); + await handler(page.Items, count, ct).ConfigureAwait(false); ++chunks; count += page.Count; } @@ -1542,7 +1542,7 @@ public static async Task ExportAsync(IFdbDatabase db, ISubspace // should export be lower priority? TODO: make if configurable! tr.Options.WithPriorityBatch(); - var folder = await path.Resolve(tr); + var folder = await path.Resolve(tr).ConfigureAwait(false); if (previous.IsNull) { if (folder == null) throw new InvalidOperationException($"Failed to export the content of subspace {path} because it was not found."); @@ -1565,7 +1565,7 @@ public static async Task ExportAsync(IFdbDatabase db, ISubspace using (var tr = db.BeginReadOnlyTransaction(ct)) { - await reset(tr); + await reset(tr).ConfigureAwait(false); //TODO: make options configurable! var options = new FdbRangeOptions @@ -1579,7 +1579,7 @@ public static async Task ExportAsync(IFdbDatabase db, ISubspace long waitForFetch = 0; // read the first batch - var page = await FetchNextBatchAsync(tr, begin, end, options, reset); + var page = await FetchNextBatchAsync(tr, begin, end, options, reset).ConfigureAwait(false); ++waitForFetch; while (page.HasMore) @@ -1591,20 +1591,20 @@ public static async Task ExportAsync(IFdbDatabase db, ISubspace if (page.Count > 0) { ct.ThrowIfCancellationRequested(); - await handler(page.Items, location, count, ct); + await handler(page.Items, location, count, ct).ConfigureAwait(false); ++chunks; count += page.Count; } if (next.Status != TaskStatus.RanToCompletion) ++waitForFetch; - page = await next; + page = await next.ConfigureAwait(false); } // process the last page, if any if (page.Count > 0) { ct.ThrowIfCancellationRequested(); - await handler(page.Items, location, count, ct); + await handler(page.Items, location, count, ct).ConfigureAwait(false); ++chunks; count += page.Count; } diff --git a/FoundationDB.Client/Fdb.System.cs b/FoundationDB.Client/Fdb.System.cs index 1577febe7..6653a7402 100644 --- a/FoundationDB.Client/Fdb.System.cs +++ b/FoundationDB.Client/Fdb.System.cs @@ -113,7 +113,7 @@ public static class System long rv = 0; if (doc.ContainsKey("cluster")) { - rv = await trans.GetReadVersionAsync(); + rv = await trans.GetReadVersionAsync().ConfigureAwait(false); } return new FdbSystemStatus(doc, rv, data); @@ -407,7 +407,7 @@ public static async Task> GetBoundaryKeysAsync(IFdbReadOnlyTransacti //TODO: we may need to also copy options like RetryLimit and Timeout ? return GetBoundaryKeysInternalAsync(shadow, beginInclusive, endExclusive); - }, trans.Cancellation); + }, trans.Cancellation).ConfigureAwait(false); } /// Returns a list of keys k such that <= k < and k is located at the start of a contiguous range stored on a single server diff --git a/FoundationDB.Client/Fdb.cs b/FoundationDB.Client/Fdb.cs index 5baacb5dd..87ef6859d 100644 --- a/FoundationDB.Client/Fdb.cs +++ b/FoundationDB.Client/Fdb.cs @@ -591,7 +591,7 @@ internal static async Task OpenInternalAsync(FdbConnectionOptions if (hasPartition) { // open the partition, and switch the root of the db - await Fdb.Directory.SwitchToNamedPartitionAsync(db, root.Path, ct); + await Fdb.Directory.SwitchToNamedPartitionAsync(db, root.Path, ct).ConfigureAwait(false); } success = true; diff --git a/FoundationDB.Client/FdbOperationContext.cs b/FoundationDB.Client/FdbOperationContext.cs index 5c41ef3d5..545ff1c35 100644 --- a/FoundationDB.Client/FdbOperationContext.cs +++ b/FoundationDB.Client/FdbOperationContext.cs @@ -74,7 +74,7 @@ public sealed class FdbOperationContext : IDisposable public FdbError PreviousError { get; private set; } /// Stopwatch that is started at the creation of the transaction, and stopped when it commits or gets disposed - private ValueStopwatch Clock; //REVIEW: must be a field! + private ValueStopwatch Clock; // must be a field! /// Duration of all the previous attempts before the current one (starts at 0, and gets updated at each reset/retry) internal TimeSpan BaseDuration { get; private set; } @@ -1062,7 +1062,7 @@ internal static async Task ExecuteInternal ExecuteInternal> f: { - result = await f(trans, intermediate!); + result = await f(trans, intermediate!).ConfigureAwait(false); hasResult = true; break; } case Func> f: { - result = await f(trans, intermediate!); + result = await f(trans, intermediate!).ConfigureAwait(false); hasResult = true; break; } case Func f: { if (!hasResult) throw new ArgumentException("Success handler requires the result to be computed by the loop handler.", nameof(success)); - await f(trans, result); + await f(trans, result).ConfigureAwait(false); break; } case Func f: { if (!hasResult) throw new ArgumentException("Success handler requires the result to be computed by the loop handler.", nameof(success)); - await f(trans, result); + await f(trans, result).ConfigureAwait(false); break; } case Func f: @@ -1175,26 +1175,26 @@ internal static async Task ExecuteInternal> f: { - result = await f(trans); + result = await f(trans).ConfigureAwait(false); hasResult = true; break; } case Func> f: { - result = await f(trans); + result = await f(trans).ConfigureAwait(false); hasResult = true; break; } case Func f: { - await f(trans); + await f(trans).ConfigureAwait(false); result = default!; hasResult = true; break; } case Func f: { - await f(trans); + await f(trans).ConfigureAwait(false); result = default!; hasResult = true; break; @@ -1223,26 +1223,26 @@ internal static async Task ExecuteInternal> f: { - result = await f(trans, intermediate!); + result = await f(trans, intermediate!).ConfigureAwait(false); hasResult = true; break; } case Func> f: { - result = await f(trans, intermediate!); + result = await f(trans, intermediate!).ConfigureAwait(false); hasResult = true; break; } case Func f: { if (!hasResult) throw new ArgumentException("Success handler requires the result to be computed by the loop handler.", nameof(success)); - await f(trans, result); + await f(trans, result).ConfigureAwait(false); break; } case Func f: { if (!hasResult) throw new ArgumentException("Success handler requires the result to be computed by the loop handler.", nameof(success)); - await f(trans, result); + await f(trans, result).ConfigureAwait(false); break; } case Func f: @@ -1253,26 +1253,26 @@ internal static async Task ExecuteInternal> f: { - result = await f(trans); + result = await f(trans).ConfigureAwait(false); hasResult = true; break; } case Func> f: { - result = await f(trans); + result = await f(trans).ConfigureAwait(false); hasResult = true; break; } case Func f: { - await f(trans); + await f(trans).ConfigureAwait(false); result = default!; hasResult = true; break; } case Func f: { - await f(trans); + await f(trans).ConfigureAwait(false); result = default!; hasResult = true; break; @@ -1344,7 +1344,7 @@ internal static async Task ExecuteInternal ExecuteInternal Clone() protected override ValueTask OnFirstAsync() { // on first call, setup the page iterator - if (m_chunkIterator == null) - { - m_chunkIterator = new PagingIterator(m_query, m_transaction).GetAsyncEnumerator(m_ct, m_mode); - } + m_chunkIterator ??= new PagingIterator(m_query, m_transaction).GetAsyncEnumerator(m_ct, m_mode); return new ValueTask(true); } @@ -151,7 +148,7 @@ private async ValueTask ReadAnotherBatchAsync() Debug.WriteLine("No more chunks from page iterator"); #endif m_outOfChunks = true; - return await Completed(); + return await Completed().ConfigureAwait(false); } private bool ProcessNextItem() @@ -191,7 +188,10 @@ protected override async ValueTask Cleanup() { try { - if (m_chunkIterator != null) await m_chunkIterator.DisposeAsync(); + if (m_chunkIterator != null) + { + await m_chunkIterator.DisposeAsync().ConfigureAwait(false); + } } finally { diff --git a/FoundationDB.Client/FdbRangeQuery.cs b/FoundationDB.Client/FdbRangeQuery.cs index bff3c6eea..a488e7627 100644 --- a/FoundationDB.Client/FdbRangeQuery.cs +++ b/FoundationDB.Client/FdbRangeQuery.cs @@ -495,10 +495,9 @@ internal async Task AnyOrNoneAsync(bool any) if ((this.TargetBytes ?? 0) != 0 || (this.Mode != FdbStreamingMode.Iterator && this.Mode != FdbStreamingMode.Exact)) { // fallback to the default implementation // ReSharper disable InvokeAsExtensionMethod - if (any) - return await AsyncEnumerable.AnyAsync(this, this.Transaction.Cancellation); - else - return await AsyncEnumerable.NoneAsync(this, this.Transaction.Cancellation); + return any + ? await AsyncEnumerable.AnyAsync(this, this.Transaction.Cancellation).ConfigureAwait(false) + : await AsyncEnumerable.NoneAsync(this, this.Transaction.Cancellation).ConfigureAwait(false); // ReSharper restore InvokeAsExtensionMethod } @@ -521,6 +520,7 @@ public override string ToString() } /// Extension methods for + [PublicAPI] public static class FdbRangeQueryExtensions { diff --git a/FoundationDB.Client/FdbTransactionExtensions.cs b/FoundationDB.Client/FdbTransactionExtensions.cs index fae249f5d..fade29168 100644 --- a/FoundationDB.Client/FdbTransactionExtensions.cs +++ b/FoundationDB.Client/FdbTransactionExtensions.cs @@ -1959,6 +1959,7 @@ public static Task> QueryAsync(this IFdbReadOnlyRetryable db, [Instan return db.ReadAsync((tr) => { var query = handler(tr) ?? throw new InvalidOperationException("The query handler returned a null sequence"); + // ReSharper disable once MethodSupportsCancellation return query.ToListAsync(); }, ct); } @@ -1976,7 +1977,8 @@ public static Task> QueryAsync(this IFdbReadOnlyRetryable db, [Instan return db.ReadAsync(async (tr) => { var query = (await handler(tr).ConfigureAwait(false)) ?? throw new InvalidOperationException("The query handler returned a null sequence"); - return await query.ToListAsync(); + // ReSharper disable once MethodSupportsCancellation + return await query.ToListAsync().ConfigureAwait(false); }, ct); } diff --git a/FoundationDB.Client/IFdbLayer.cs b/FoundationDB.Client/IFdbLayer.cs index 393f9ef2f..e7789ad89 100644 --- a/FoundationDB.Client/IFdbLayer.cs +++ b/FoundationDB.Client/IFdbLayer.cs @@ -57,6 +57,7 @@ public interface IFdbLayer /// Set of helper methods for working with instances + [PublicAPI] public static class FdbLayerExtensions { @@ -81,8 +82,8 @@ public static Task ReadAsync( (layer, handler), async (tr, s) => { - var state = await (s.layer).Resolve(tr); - return await s.handler(tr, state); + var state = await (s.layer).Resolve(tr).ConfigureAwait(false); + return await s.handler(tr, state).ConfigureAwait(false); }, ct); } @@ -109,8 +110,8 @@ public static Task ReadAsync( (layer, handler), async (tr, s) => { - var state = await (s.layer).Resolve(tr); - await s.handler(tr, state); + var state = await (s.layer).Resolve(tr).ConfigureAwait(false); + await s.handler(tr, state).ConfigureAwait(false); }, ct); } @@ -136,8 +137,8 @@ public static Task ReadWriteAsync( (layer, handler), async (tr, s) => { - var state = await (s.layer).Resolve(tr); - return await s.handler(tr, state); + var state = await (s.layer).Resolve(tr).ConfigureAwait(false); + return await s.handler(tr, state).ConfigureAwait(false); }, ct); } @@ -162,7 +163,7 @@ public static Task WriteAsync( (layer, handler), async (tr, s) => { - var state = await (s.layer).Resolve(tr); + var state = await (s.layer).Resolve(tr).ConfigureAwait(false); s.handler(tr, state); }, ct); @@ -188,8 +189,8 @@ public static Task WriteAsync( (layer, handler), async (tr, s) => { - var state = await (s.layer).Resolve(tr); - await s.handler(tr, state); + var state = await (s.layer).Resolve(tr).ConfigureAwait(false); + await s.handler(tr, state).ConfigureAwait(false); }, ct); } diff --git a/FoundationDB.Client/Layers/Directories/Fdb.Directory.cs b/FoundationDB.Client/Layers/Directories/Fdb.Directory.cs index 43e1d0c31..13d223f46 100644 --- a/FoundationDB.Client/Layers/Directories/Fdb.Directory.cs +++ b/FoundationDB.Client/Layers/Directories/Fdb.Directory.cs @@ -75,7 +75,8 @@ public static async Task> BrowseAsync(I var folders = await children .ToAsyncEnumerable() .SelectAsync((child, _) => parent.OpenAsync(tr, FdbPath.Relative(child.Name))) - .ToListAsync(); + .ToListAsync() + .ConfigureAwait(false); // map the result return folders.ToDictionary(ds => ds.Name); diff --git a/FoundationDB.Client/Layers/Directories/FdbDirectorySubspace.cs b/FoundationDB.Client/Layers/Directories/FdbDirectorySubspace.cs index bb2146eed..e3936bca5 100644 --- a/FoundationDB.Client/Layers/Directories/FdbDirectorySubspace.cs +++ b/FoundationDB.Client/Layers/Directories/FdbDirectorySubspace.cs @@ -45,7 +45,7 @@ public class FdbDirectorySubspace : DynamicKeySubspace, IFdbDirectory internal FdbDirectorySubspace(FdbDirectoryLayer.DirectoryDescriptor descriptor, IDynamicKeyEncoder encoder, ISubspaceContext? context, bool cached) : base(descriptor.Prefix, encoder, context ?? SubspaceContext.Default) { - Contract.Debug.Requires(descriptor?.Partition != null); + Contract.Debug.Requires(descriptor != null && descriptor.Partition != null); this.Descriptor = descriptor; this.Cached = cached; } @@ -146,7 +146,7 @@ public async Task ChangeLayerAsync(IFdbTransaction trans, EnsureIsValid(); // set the layer to the new value - var metadata = await this.DirectoryLayer.Resolve(trans); + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); await metadata.ChangeLayerInternalAsync(trans, descriptor.Path, newLayer).ConfigureAwait(false); // and return the new version of the subspace @@ -168,8 +168,8 @@ public async Task CreateOrOpenAsync(IFdbTransaction trans, EnsureIsValid(); - var metadata = await this.DirectoryLayer.Resolve(trans); - return (await metadata.CreateOrOpenInternalAsync(null, trans, ToAbsolutePath(path), Slice.Nil, allowCreate: true, allowOpen: true, throwOnError: true))!; + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return (await metadata.CreateOrOpenInternalAsync(null, trans, ToAbsolutePath(path), Slice.Nil, allowCreate: true, allowOpen: true, throwOnError: true).ConfigureAwait(false))!; } /// Opens a sub-directory with the given . @@ -177,7 +177,6 @@ public async Task CreateOrOpenAsync(IFdbTransaction trans, /// /// Transaction to use for the operation /// Relative path of the sub-directory to open - /// If specified, the opened directory must have the same layer id. public async Task OpenAsync(IFdbReadOnlyTransaction trans, FdbPath path) { Contract.NotNull(trans); @@ -185,8 +184,8 @@ public async Task OpenAsync(IFdbReadOnlyTransaction trans, EnsureIsValid(); - var metadata = await this.DirectoryLayer.Resolve(trans); - return (await metadata.CreateOrOpenInternalAsync(trans, null, ToAbsolutePath(path), prefix: Slice.Nil, allowCreate: false, allowOpen: true, throwOnError: true))!; + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return (await metadata.CreateOrOpenInternalAsync(trans, null, ToAbsolutePath(path), prefix: Slice.Nil, allowCreate: false, allowOpen: true, throwOnError: true).ConfigureAwait(false))!; } /// Opens a sub-directory with the given . @@ -194,7 +193,6 @@ public async Task OpenAsync(IFdbReadOnlyTransaction trans, /// /// Transaction to use for the operation /// Relative path of the sub-directory to open - /// If specified, the opened directory must have the same layer id. /// Returns the directory if it exists, or null if it was not found public async Task TryOpenAsync(IFdbReadOnlyTransaction trans, FdbPath path) { @@ -203,8 +201,8 @@ public async Task OpenAsync(IFdbReadOnlyTransaction trans, EnsureIsValid(); - var metadata = await this.DirectoryLayer.Resolve(trans); - return await metadata.CreateOrOpenInternalAsync(trans, null, ToAbsolutePath(path), prefix: Slice.Nil, allowCreate: false, allowOpen: true, throwOnError: false); + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return await metadata.CreateOrOpenInternalAsync(trans, null, ToAbsolutePath(path), prefix: Slice.Nil, allowCreate: false, allowOpen: true, throwOnError: false).ConfigureAwait(false); } public async ValueTask TryOpenCachedAsync(IFdbReadOnlyTransaction trans, FdbPath path) @@ -214,8 +212,8 @@ public async Task OpenAsync(IFdbReadOnlyTransaction trans, EnsureIsValid(); - var metadata = await this.DirectoryLayer.Resolve(trans); - return await metadata.OpenCachedInternalAsync(trans, ToAbsolutePath(path), throwOnError: false); + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return await metadata.OpenCachedInternalAsync(trans, ToAbsolutePath(path), throwOnError: false).ConfigureAwait(false); } public async ValueTask TryOpenCachedAsync(IFdbReadOnlyTransaction trans, IEnumerable paths) @@ -227,8 +225,8 @@ public async Task OpenAsync(IFdbReadOnlyTransaction trans, var items = (paths as FdbPath[]) ?? paths.ToArray(); - var metadata = await this.DirectoryLayer.Resolve(trans); - return await metadata.OpenCachedInternalAsync(trans, items, throwOnError: false); + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return await metadata.OpenCachedInternalAsync(trans, items, throwOnError: false).ConfigureAwait(false); } /// Creates a sub-directory with the given (creating intermediate subdirectories if necessary). @@ -271,8 +269,8 @@ public async Task RegisterAsync(IFdbTransaction trans, Fdb if (path.IsEmpty) throw new ArgumentNullException(nameof(path)); EnsureIsValid(); - var metadata = await this.DirectoryLayer.Resolve(trans); - return (await metadata.CreateOrOpenInternalAsync(null, trans, ToAbsolutePath(path), prefix: prefix, allowCreate: true, allowOpen: false, throwOnError: true))!; + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return (await metadata.CreateOrOpenInternalAsync(null, trans, ToAbsolutePath(path), prefix: prefix, allowCreate: true, allowOpen: false, throwOnError: true).ConfigureAwait(false))!; } /// Moves the current directory to . @@ -294,8 +292,8 @@ public async Task MoveToAsync(IFdbTransaction trans, FdbPa var location = this.DirectoryLayer.VerifyPath(newAbsolutePath, "newAbsolutePath"); if (!location.StartsWith(partition.Path)) throw new InvalidOperationException($"Cannot move between partitions ['{location}' is outside '{partition.Path}']"); - var metadata = await this.DirectoryLayer.Resolve(trans); - return (await metadata.MoveInternalAsync(trans, this.Descriptor.Path, location, throwOnError: true))!; + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return (await metadata.MoveInternalAsync(trans, this.Descriptor.Path, location, throwOnError: true).ConfigureAwait(false))!; } /// Moves the specified sub-directory to . @@ -312,8 +310,8 @@ async Task IFdbDirectory.MoveAsync(IFdbTransaction trans, if (newPath.IsEmpty) throw new ArgumentNullException(nameof(newPath)); EnsureIsValid(); - var metadata = await this.DirectoryLayer.Resolve(trans); - return (await metadata.MoveInternalAsync(trans, ToAbsolutePath(oldPath), ToAbsolutePath(newPath), throwOnError: true))!; + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return (await metadata.MoveInternalAsync(trans, ToAbsolutePath(oldPath), ToAbsolutePath(newPath), throwOnError: true).ConfigureAwait(false))!; } /// Attempts to move the current directory to . @@ -366,8 +364,8 @@ public async Task RemoveAsync(IFdbTransaction trans) var descriptor = this.Descriptor; - var metadata = await descriptor.DirectoryLayer.Resolve(trans); - await metadata.RemoveInternalAsync(trans, descriptor.Path, throwIfMissing: true); + var metadata = await descriptor.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + await metadata.RemoveInternalAsync(trans, descriptor.Path, throwIfMissing: true).ConfigureAwait(false); } /// Removes a sub-directory, its contents, and all subdirectories. @@ -404,8 +402,8 @@ public async Task TryRemoveAsync(IFdbTransaction trans) var descriptor = this.Descriptor; - var metadata = await descriptor.DirectoryLayer.Resolve(trans); - return await metadata.RemoveInternalAsync(trans, descriptor.Path, throwIfMissing: false); + var metadata = await descriptor.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return await metadata.RemoveInternalAsync(trans, descriptor.Path, throwIfMissing: false).ConfigureAwait(false); } /// Attempts to remove a sub-directory, its contents, and all subdirectories. @@ -422,11 +420,11 @@ public async Task TryRemoveAsync(IFdbTransaction trans, FdbPath path) var location = this.DirectoryLayer.VerifyPath(path, nameof(path)); if (location.Count == 0) { - return await TryRemoveAsync(trans); + return await TryRemoveAsync(trans).ConfigureAwait(false); } - var metadata = await this.DirectoryLayer.Resolve(trans); - return await metadata.RemoveInternalAsync(trans, ToAbsolutePath(location), throwIfMissing: false); + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return await metadata.RemoveInternalAsync(trans, ToAbsolutePath(location), throwIfMissing: false).ConfigureAwait(false); } /// Checks if this directory exists @@ -438,8 +436,8 @@ public async Task ExistsAsync(IFdbReadOnlyTransaction trans) var descriptor = this.Descriptor; - var metadata = await descriptor.DirectoryLayer.Resolve(trans); - return await metadata.ExistsInternalAsync(trans, descriptor.Path); + var metadata = await descriptor.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return await metadata.ExistsInternalAsync(trans, descriptor.Path).ConfigureAwait(false); } /// Checks if a sub-directory exists @@ -453,11 +451,11 @@ public async Task ExistsAsync(IFdbReadOnlyTransaction trans, FdbPath path) var location = this.DirectoryLayer.VerifyPath(path, nameof(path)); if (location.Count == 0) { - return await ExistsAsync(trans); + return await ExistsAsync(trans).ConfigureAwait(false); } - var metadata = await this.DirectoryLayer.Resolve(trans); - return await metadata.ExistsInternalAsync(trans, ToAbsolutePath(location)); + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return await metadata.ExistsInternalAsync(trans, ToAbsolutePath(location)).ConfigureAwait(false); } /// Returns the list of all the subdirectories of a sub-directory. @@ -466,8 +464,8 @@ public async Task> ListAsync(IFdbReadOnlyTransaction trans, FdbPat Contract.NotNull(trans); EnsureIsValid(); - var metadata = await this.DirectoryLayer.Resolve(trans); - return (await metadata.ListInternalAsync(trans, ToAbsolutePath(path), throwIfMissing: true))!; + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return (await metadata.ListInternalAsync(trans, ToAbsolutePath(path), throwIfMissing: true).ConfigureAwait(false))!; } /// Returns the list of all the subdirectories of the current directory, it it exists. @@ -476,13 +474,13 @@ public async Task> ListAsync(IFdbReadOnlyTransaction trans, FdbPat Contract.NotNull(trans); EnsureIsValid(); - var metadata = await this.DirectoryLayer.Resolve(trans); - return await metadata.ListInternalAsync(trans, ToAbsolutePath(path), throwIfMissing: false); + var metadata = await this.DirectoryLayer.Resolve(trans).ConfigureAwait(false); + return await metadata.ListInternalAsync(trans, ToAbsolutePath(path), throwIfMissing: false).ConfigureAwait(false); } public override string DumpKey(Slice key, bool absolute = false) { - return absolute ? $"[/{this.FullName}]:{base.DumpKey(key, false)}" : base.DumpKey(key, false); + return absolute ? $"[/{this.FullName}]:{base.DumpKey(key, absolute: false)}" : base.DumpKey(key, absolute: false); } /// Returns a user-friendly description of this directory diff --git a/FoundationDB.Client/Layers/Directories/FdbDirectorySubspaceLocation.cs b/FoundationDB.Client/Layers/Directories/FdbDirectorySubspaceLocation.cs index b5a4edfca..f42ba55fa 100644 --- a/FoundationDB.Client/Layers/Directories/FdbDirectorySubspaceLocation.cs +++ b/FoundationDB.Client/Layers/Directories/FdbDirectorySubspaceLocation.cs @@ -67,7 +67,7 @@ public FdbDirectorySubspaceLocation(FdbPath path) /// async ValueTask ISubspaceLocation.Resolve(IFdbReadOnlyTransaction tr, FdbDirectoryLayer? directory) { - return await Resolve(tr, directory); + return await Resolve(tr, directory).ConfigureAwait(false); } public ValueTask Resolve(IFdbReadOnlyTransaction tr, FdbDirectoryLayer? directory = null) @@ -88,9 +88,9 @@ public FdbDirectorySubspaceLocation(FdbPath path) static async ValueTask ResolveOrCreate(IFdbTransaction tr, FdbDirectoryLayer? directory, FdbPath path) { directory ??= tr.Context.Database.DirectoryLayer; - var subspace = await directory.TryOpenCachedAsync(tr, path); + var subspace = await directory.TryOpenCachedAsync(tr, path).ConfigureAwait(false); if (subspace != null) return subspace; - subspace = await directory.CreateAsync(tr, path); + subspace = await directory.CreateAsync(tr, path).ConfigureAwait(false); //TODO: how to handle the cache? return subspace; } @@ -123,7 +123,7 @@ internal FdbPath GetSafePath() } /// Append a segment to the current path - public FdbDirectorySubspaceLocation this[FdbPathSegment segment] => new FdbDirectorySubspaceLocation(this.Path.Add(segment)); + public FdbDirectorySubspaceLocation this[FdbPathSegment segment] => new(this.Path.Add(segment)); /// Append one or more segments to the current path public FdbDirectorySubspaceLocation this[ReadOnlySpan segments] => segments.Length != 0 ? new FdbDirectorySubspaceLocation(this.Path.Add(segments)) : this; @@ -131,12 +131,12 @@ internal FdbPath GetSafePath() /// Append a segment to the current path /// Name of the segment /// The new segment will not have a layer id. - public FdbDirectorySubspaceLocation this[string name] => new FdbDirectorySubspaceLocation(this.Path.Add(FdbPathSegment.Create(name))); + public FdbDirectorySubspaceLocation this[string name] => new(this.Path.Add(FdbPathSegment.Create(name))); /// Append a segment - composed of a name and layer id - to the current path /// Name of the segment /// Layer Id of the segment - public FdbDirectorySubspaceLocation this[string name, string layerId] => new FdbDirectorySubspaceLocation(this.Path.Add(new FdbPathSegment(name, layerId))); + public FdbDirectorySubspaceLocation this[string name, string layerId] => new(this.Path.Add(new FdbPathSegment(name, layerId))); /// Append a relative path to the current path public FdbDirectorySubspaceLocation this[FdbPath relativePath] => !relativePath.IsEmpty ? new FdbDirectorySubspaceLocation(this.Path.Add(relativePath)) : this; @@ -145,7 +145,7 @@ internal FdbPath GetSafePath() /// Type of the key /// Key that will be appended to the current location's binary prefix /// A new subspace location with an additional binary suffix - public DynamicKeySubspaceLocation ByKey(T1 item1) => new DynamicKeySubspaceLocation(GetSafePath(), TuPack.EncodeKey(item1), TuPack.Encoding.GetDynamicKeyEncoder()); + public DynamicKeySubspaceLocation ByKey(T1 item1) => new(GetSafePath(), TuPack.EncodeKey(item1), TuPack.Encoding.GetDynamicKeyEncoder()); /// Append a pair encoded keys to the prefix of the current location /// Type of the first key @@ -153,7 +153,7 @@ internal FdbPath GetSafePath() /// Key that will be appended first to the current location's binary prefix /// Key that will be appended last to the current location's binary prefix /// A new subspace location with an additional binary suffix - public DynamicKeySubspaceLocation ByKey(T1 item1, T2 item2) => new DynamicKeySubspaceLocation(GetSafePath(), TuPack.EncodeKey(item1, item2), TuPack.Encoding.GetDynamicKeyEncoder()); + public DynamicKeySubspaceLocation ByKey(T1 item1, T2 item2) => new(GetSafePath(), TuPack.EncodeKey(item1, item2), TuPack.Encoding.GetDynamicKeyEncoder()); #region IFdbDirectory... diff --git a/FoundationDB.Client/Subspaces/SubspaceLocation.cs b/FoundationDB.Client/Subspaces/SubspaceLocation.cs index 0e7598341..cd497c648 100644 --- a/FoundationDB.Client/Subspaces/SubspaceLocation.cs +++ b/FoundationDB.Client/Subspaces/SubspaceLocation.cs @@ -119,7 +119,7 @@ public override string ToString() async ValueTask ISubspaceLocation.Resolve(IFdbReadOnlyTransaction tr, FdbDirectoryLayer? directory) { - return await Resolve(tr, directory); + return await Resolve(tr, directory).ConfigureAwait(false); } public abstract ValueTask Resolve(IFdbReadOnlyTransaction tr, FdbDirectoryLayer? directory = null); @@ -150,7 +150,7 @@ public BinaryKeySubspaceLocation(in FdbPath path, in Slice suffix) public override int GetHashCode() => HashCodes.Combine(this.Path.GetHashCode(), this.Prefix.GetHashCode(), 0x12345678); public override bool Equals(ISubspaceLocation? other) => - object.ReferenceEquals(other, this) + ReferenceEquals(other, this) || (other is BinaryKeySubspaceLocation bin && bin.Path == this.Path && bin.Prefix == other.Prefix); public override ValueTask Resolve(IFdbReadOnlyTransaction tr, FdbDirectoryLayer? directory = null) @@ -165,7 +165,7 @@ public override bool Equals(ISubspaceLocation? other) => private async ValueTask ResolveWithDirectory(IFdbReadOnlyTransaction tr, FdbDirectoryLayer? directory) { // located inside a directory subspace! - var folder = await (directory ?? tr.Context.Database.DirectoryLayer).TryOpenCachedAsync(tr, this.Path); + var folder = await (directory ?? tr.Context.Database.DirectoryLayer).TryOpenCachedAsync(tr, this.Path).ConfigureAwait(false); if (folder == null) return null; if (this.Prefix.Count == 0) return folder; return new BinaryKeySubspace(folder.GetPrefix() + this.Prefix, folder.Context); @@ -217,7 +217,7 @@ public DynamicKeySubspaceLocation(in Slice prefix, IDynamicKeyEncoder encoder) public override int GetHashCode() => HashCodes.Combine(this.Path.GetHashCode(), this.Prefix.GetHashCode(), 0x12344321); public override bool Equals(ISubspaceLocation? other) => - object.ReferenceEquals(other, this) + ReferenceEquals(other, this) || (other is DynamicKeySubspaceLocation dyn && dyn.Encoding == this.Encoding && dyn.Path == this.Path && dyn.Prefix == other.Prefix); public override ValueTask Resolve(IFdbReadOnlyTransaction tr, FdbDirectoryLayer? directory = null) @@ -286,7 +286,7 @@ public TypedKeySubspaceLocation(FdbPath path, Slice suffix, IKeyEncoder enco public override int GetHashCode() => HashCodes.Combine(this.Path.GetHashCode(), this.Prefix.GetHashCode(), 0x1111); public override bool Equals(ISubspaceLocation? other) => - object.ReferenceEquals(other, this) + ReferenceEquals(other, this) || (other is TypedKeySubspaceLocation typed && typed.Encoding == this.Encoding && typed.Path == this.Path && typed.Prefix == other.Prefix); /// @@ -340,7 +340,7 @@ public TypedKeySubspaceLocation(FdbPath path, Slice suffix, ICompositeKeyEncoder public override int GetHashCode() => HashCodes.Combine(this.Path.GetHashCode(), this.Prefix.GetHashCode(), 0x2222); public override bool Equals(ISubspaceLocation? other) => - object.ReferenceEquals(other, this) + ReferenceEquals(other, this) || (other is TypedKeySubspaceLocation typed && typed.Encoding == this.Encoding && typed.Path == this.Path && typed.Prefix == other.Prefix); /// @@ -397,7 +397,7 @@ public TypedKeySubspaceLocation(FdbPath path, Slice suffix, ICompositeKeyEncoder public override int GetHashCode() => HashCodes.Combine(this.Path.GetHashCode(), this.Prefix.GetHashCode(), 0x3333); public override bool Equals(ISubspaceLocation? other) => - object.ReferenceEquals(other, this) + ReferenceEquals(other, this) || (other is TypedKeySubspaceLocation typed && typed.Encoding == this.Encoding && typed.Path == this.Path && typed.Prefix == other.Prefix); public override ValueTask?> Resolve(IFdbReadOnlyTransaction tr, FdbDirectoryLayer? directory = null) @@ -454,7 +454,7 @@ public TypedKeySubspaceLocation(FdbPath path, Slice suffix, ICompositeKeyEncoder public override int GetHashCode() => HashCodes.Combine(this.Path.GetHashCode(), this.Prefix.GetHashCode(), 0x4444); public override bool Equals(ISubspaceLocation? other) => - object.ReferenceEquals(other, this) + ReferenceEquals(other, this) || (other is TypedKeySubspaceLocation typed && typed.Encoding == this.Encoding && typed.Path == this.Path && typed.Prefix == other.Prefix); public override ValueTask?> Resolve(IFdbReadOnlyTransaction tr, FdbDirectoryLayer? directory = null) diff --git a/FoundationDB.Client/Tenants/FdbTenantManagement.cs b/FoundationDB.Client/Tenants/FdbTenantManagement.cs index 6198ca884..d075c029c 100644 --- a/FoundationDB.Client/Tenants/FdbTenantManagement.cs +++ b/FoundationDB.Client/Tenants/FdbTenantManagement.cs @@ -46,6 +46,7 @@ public enum FdbTenantMode public static partial class Fdb { + [PublicAPI] public static class Tenants { @@ -61,7 +62,7 @@ public static class Tenants public static async Task GetTenantMode(IFdbReadOnlyTransaction tr) { tr.Options.WithReadAccessToSystemKeys(); - var val = await tr.GetAsync(TenantModeKey); + var val = await tr.GetAsync(TenantModeKey).ConfigureAwait(false); if (val.IsNullOrEmpty) return FdbTenantMode.Disabled; // this is a number represented as a decimal string // so "0" is Disabled, "1" is Optional, etc.. @@ -84,7 +85,7 @@ public static void CreateTenant(IFdbTransaction tr, FdbTenantName name) public static async Task HasTenant(IFdbReadOnlyTransaction tr, FdbTenantName name) { - var value = await tr.GetAsync(TenantMapPrefix + name.Value); + var value = await tr.GetAsync(TenantMapPrefix + name.Value).ConfigureAwait(false); return value.HasValue; } @@ -127,7 +128,7 @@ private static FdbTenantMetadata ParseTenantMetadata(FdbTenantName name, Slice d public static async Task GetTenantMetadata(IFdbReadOnlyTransaction tr, FdbTenantName name) { - var data = await tr.GetAsync(TenantMapPrefix + name.Value); + var data = await tr.GetAsync(TenantMapPrefix + name.Value).ConfigureAwait(false); return data.HasValue ? ParseTenantMetadata(name, data) : null; } diff --git a/FoundationDB.Client/Tracing/FdbTransactionLog.Commands.cs b/FoundationDB.Client/Tracing/FdbTransactionLog.Commands.cs index 689a42801..84da71893 100644 --- a/FoundationDB.Client/Tracing/FdbTransactionLog.Commands.cs +++ b/FoundationDB.Client/Tracing/FdbTransactionLog.Commands.cs @@ -297,12 +297,12 @@ public DirectoryKeyResolver(Dictionary knownSubspaces) /// Resolver that replace each directory prefix by its name public static async Task BuildFromDirectoryLayer(IFdbReadOnlyTransaction tr, FdbDirectoryLayer directory) { - var metadata = await directory.Resolve(tr); + var metadata = await directory.Resolve(tr).ConfigureAwait(false); var location = metadata.Partition.Nodes; //HACKHACK: for now, we will simply poke inside the node subspace of the directory layer, which is brittle (if the structure changes in future versions!) // Entries that correspond to subfolders have the form: NodeSubspace.Pack( (parent_prefix, 0, "child_name") ) = child_prefix - var keys = await tr.GetRange(location.ToRange()).ToListAsync(); + var keys = await tr.GetRange(location.ToRange()).ToListAsync().ConfigureAwait(false); var map = new Dictionary(Slice.Comparer.Default);