Interface TenantControl

All Superinterfaces:
DataSerializable

@Beta public interface TenantControl extends DataSerializable
Hooks for multi-tenancy for application servers. It captures a thread-local context which can then be used to re-establish the same context on different threads.

For example, an instance of tenant control can be created on an application thread and this tenant control can then be used to establish the same context on a different thread, e.g. OperationThread. Operation invocations requiring such context can then be handled correctly.

This is used by application servers to establish thread context for class loading, CDI, EJB and JPA invocations

Caveats

  • Tenant control context is captured on the application thread once the user interacts with distributed data structure proxies. In some cases, these proxies might be instantiated as a result of other, internal, actions such as Hot Restart, WAN replication. Proxies on the member-side might also be created as a consequence of the user creating a proxy on a client. In all these cases, the tenant control context is not captured correctly and this feature will not work as expected.
  • When the tenant is not available, operations requiring tenant control should be re-enqueued for later execution. This only includes operations which were enqueued on the operation queue in the first place and does not include operations which were run directly on the thread running the operations, without being enqueued. This includes operations that are run as a consequence of another operation, such as a map.get blocking on a locked entry being unblocked by an unlock operation.
Author:
lprimak
  • Field Details

    • NOOP_TENANT_CONTROL

      static final TenantControl NOOP_TENANT_CONTROL
      Default no-op tenant control
  • Method Details

    • setTenant

      Establish this tenant's thread-local context. The implementation can control the details of what kind of context to set and how to establish it.
      Returns:
      handle to be able to close the tenant's scope.
    • registerObject

      void registerObject(@Nonnull DestroyEventContext destroyEventContext)
      Registers a hook to decouple any Hazelcast object when the tenant is destroyed, This is used, for example, to delete all associated caches from the application when it gets undeployed, so there are no ClassCastException afterwards.
      Parameters:
      destroyEventContext - the hook to be used by the tenant control implementation Cannot be null. This is a functional interface, so no-op lambda can be used instead.
    • unregisterObject

      void unregisterObject()
      Invoked when the distributed object belonging to this tenant control has been destroyed. The implementation can undo whatever was done in registerObject(DestroyEventContext). This is so the TenantControl itself can be garbage collected.
    • isAvailable

      boolean isAvailable(@Nonnull Tenantable tenantable)
      Checks if the tenant app is loaded and classes are available for the given Tenantable object.
      Parameters:
      tenantable - passed so the tenant can filter on which object is calling
      Returns:
      true if tenant is loaded and classes are available
    • clearThreadContext

      void clearThreadContext()
      Cleans up all of the thread context to avoid potential class loader leaks This method should clear all potential context items, not just the ones set up in setTenant() This acts as a catch-all for any potential class loader and thread-local leaks.