Doxense / foundationdb-dotnet-client

C#/.NET Binding for FoundationDB Client API
BSD 3-Clause "New" or "Revised" License
149 stars 33 forks source link

Refactor "Options" API to be more in line with other bindings #121

Closed KrzysFR closed 4 days ago

KrzysFR commented 1 year ago

Looking at bindings for other languages, the transaction options are usually accessed via an "Options" property or field, so would look something like this in c#

tr.Options.Timeout = 10;
tr.Options.SetOption(FdbTransactionOption.AccessSystemKeys);

Currently, the SetOptions(...) methods are directly on the IFdbReadOnlyTransaction itself, and there is a set of extensions methods that target this interface to add the fluent versions of WithWriteAccessToSystemKeys(...) or WithNextWriteNoWriteConflictRange(..) etc..

These methods would be moved to a new IFdbTransactionOptions interface, and accessible via the tr.Options field.

Typical usage:

var results = await db.ReadWriteAsync(tr =>
{
     tr.Options.RetryLimit = 10;
     tr.Options.WithWriteAccessToSystemKeys();
     tr.Options.WithNextWriteNoWriteConflictRange();
     return tr.GetRange(....).Select(....).ToArrayAsync();
}, ct);

To keep an easy way to perform fluent configuration and query of a transaction (combined with the QueryAsync(...) helper, we would add a WithOptions(Action<IFdbTranscationOptions>) on the transaction itself, that would return the transaction instance. This would allow the caller to have the transaction handler expressed as a single expression, without the need to create a statement or block.

var res = tr.WithOptions(options => options.WithWriteAccessToSystemKeys().WithNextWriteNoWriteConflictRange())
                  .GetRange(....)
                  .Select(...)
                  .ToArrayAsync()

Pro:

Drawbacks:

KrzysFR commented 4 days ago

Changes have been made as described. The default database options can also be configured by the connection string injected by the Aspire integration:

For example, in the AppHost, default values for timeouts, retry limits and default tracing options are provided. All other resources that reference the fdb cluster resource will inherit these options, which are transmitted via the connection string by the Aspire host:

var fdb = builder
  .AddFoundationDb("fdb", apiVersion: 730, root: "/Sandbox/HelloWorld", clusterVersion: "7.3.54", rollForward: FdbVersionPolicy.Exact)
  .WithDefaults(timeout: TimeSpan.FromSeconds(15), retryLimit: 10, tracing: FdbTracingOptions.All)
  .WithLifetime(ContainerLifetime.Persistent)
  ;

The options will be applied as the default database options in each process when it calls builder.AddFoundationDb("fdb", ...), and thus be the default values for each transaction as well.