Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Tenants #117

Open
KrzysFR opened this issue May 15, 2023 · 1 comment
Open

Add support for Tenants #117

KrzysFR opened this issue May 15, 2023 · 1 comment
Labels
api Issues or changes related to the client API enhancement native Interop with the native client library

Comments

@KrzysFR
Copy link
Member

KrzysFR commented May 15, 2023

We need to add support for Tenants (https://apple.github.io/foundationdb/tenants.html) and the associated FDBTenant API (https://apple.github.io/foundationdb/api-c.html#c.FDBTenant)

If I understand correctly, it is an abstraction that is inserted between the Database and the Transaction:

  • From the database handle, you can create a tenant handle, referenced via a "tenant name" (byte string)
  • From this tenant handler, you can start transactions.
  • These transactions are "isolated" and each have their own keyspace: Both tenants A and B could read and write to the key hello without interference
  • A transaction created outside of a tenant would see the keys of both tenants, prefixed by each tenant's prefix (so it would see ${A_PREFIX}hello and ${B_PREFIX}hello.
  • There seems to be a set of global cluster options that allow or disallow working outside of a tenant (tenant_mode).

Transaction created from the IFdbDatabase act as usual, but transactions created from the IFdbTenant are working on a completely isolated key space, that is the logical equivalent of a Directory Partition: each "tenant" is associated with a unique key prefix that is added to the key, before being stored in the global keyspace.

This looks very similar to what we currently do when "pinning" the FDBDatabase object to a specific partition, except that with tenant, the common key prefix is removed from the view of the application, while with partitions it is still visible.

API

We should add the IFdbTenant interface to represent a specific Tenant. Instances of this type could be obtained through the IFdbDatabase instance (with forwarders on the IFdbDatabaseProvider for easy access).

TODO: investigate the lifetime of instances of FDBTenant*

  • Can one reuse the same tenant handle for as many transactions as required?
  • What happens if multiple tenant handler are opened with the same name?
  • What happens if the prefix of a tenant changes AFTER a tenant handle has been created? Will it automatically see the new prefix?
  • What happens if a tenant is deleted after a tenant handler has been created? Will the operation fail immediately? when starting the transaction? during the first read?

If the FDBTenant handle are long-lived, it would be a good idea to cache them, so that obtaining the instance for a specific name, from inside an http request handler would be cheap (same as IFdbDatabaseProvider where the ValueTask is async on the first call, and cached for subsequent calls).

If the FDBTenant handle does not detect that the prefix has changed, maybe we could use deferred value checks for still allow caching of these? (using the IFdbLayer convention).

@KrzysFR KrzysFR added enhancement api Issues or changes related to the client API native Interop with the native client library labels May 15, 2023
@KrzysFR
Copy link
Member Author

KrzysFR commented Jun 5, 2023

The current state is that tenants are via the db.GetTenant(...) method that returns a (long lived) IFdbTenant instance, which acts the same way as an IFdbDatabase instance (implements IFdbRetryable). Tenant names are wrapper in an FdbTenantName helper struct which handles most of the way one could want to represent names (tuples, binary literals, ...) and adds a nicer ToString() for debugging purpose.

So typical usage would be:

async Task DoSomething(IFdbDatabase db, FdbTenantName tenant, ...., CancellationToken ct)
{
    var res = await db.GetTenant(tenant).ReadWriteAsync(tr => ....., ct);
    ....
}

The transaction will be attached to the tenant, and be "chroot-ed" inside this tenant keyspace prefix.

To manage tenants (add, delete, list) there are a set of methods on the static class Fdb.Tenants, for example Fdb.Tenants.CreateTenant(....) or Fdb.Tenants.DeleteTenant(...).

Tenant metadata are exposed via the Fdb.Tenants.GetTenantMetadata(....) that returns an instance of FdbTenantMetdata that contains the uniquely assigned Id as well as the binary prefix of this tenant (from the global keyspace).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api Issues or changes related to the client API enhancement native Interop with the native client library
Projects
None yet
Development

No branches or pull requests

1 participant