Class LeaseManager

java.lang.Object
com.loomcache.server.lease.LeaseManager

public class LeaseManager extends Object
Manages etcd-style time-bound TTL leases.

This manager creates and tracks leases with automatic TTL expiry detection. A background virtual thread monitors leases every second and auto-revokes expired ones, triggering key deletion callbacks for all attached keys.

Thread-safe: uses ConcurrentHashMap and AtomicLong for all shared state. Virtual threads handle the background expiry check without blocking the main application threads.

Lifecycle: Call start() to begin the background monitor and shutdown() to gracefully stop it.

Since:
1.5
  • Constructor Details

    • LeaseManager

      public LeaseManager(Consumer<String> onKeyExpiry)
      Creates a new LeaseManager.
      Parameters:
      onKeyExpiry - callback invoked for each key when its lease expires
      Throws:
      NullPointerException - if onKeyExpiry is null
  • Method Details

    • grant

      public Lease grant(long ttlSeconds)
      Grants a new lease with the given TTL.

      The lease ID is auto-generated using an atomic counter. The lease is immediately ready to use and can have keys attached.

      Parameters:
      ttlSeconds - the time-to-live in seconds (must be positive)
      Returns:
      a newly created and tracked Lease
      Throws:
      IllegalArgumentException - if ttlSeconds <= 0
    • revoke

      public boolean revoke(long leaseId)
      Revokes a lease and removes all its attached keys.

      For each attached key, the onKeyExpiry callback is invoked to allow the cache to delete the key.

      Parameters:
      leaseId - the ID of the lease to revoke
      Returns:
      true if the lease existed and was revoked, false if not found
    • renew

      public boolean renew(long leaseId, long newTtlSeconds)
      Renews a lease by extending its TTL.

      Updates the lastRenewedAt timestamp of the lease, effectively resetting the TTL countdown.

      Parameters:
      leaseId - the ID of the lease to renew
      newTtlSeconds - the new TTL in seconds (must be positive)
      Returns:
      true if the lease was renewed, false if the lease was not found
      Throws:
      IllegalArgumentException - if newTtlSeconds <= 0
    • attachKey

      public boolean attachKey(long leaseId, String key)
      Attaches a key to a lease.

      If the lease does not exist, this is a no-op and returns false.

      Parameters:
      leaseId - the ID of the lease
      key - the key to attach (must not be null)
      Returns:
      true if the key was attached, false if the lease was not found
      Throws:
      NullPointerException - if key is null
    • detachKey

      public boolean detachKey(long leaseId, @Nullable String key)
      Detaches a key from a lease.

      If the lease does not exist, this is a no-op and returns false.

      Parameters:
      leaseId - the ID of the lease
      key - the key to detach (may be null)
      Returns:
      true if the key was detached, false if the lease was not found
    • getLease

      public Optional<Lease> getLease(long leaseId)
      Retrieves a lease by ID.
      Parameters:
      leaseId - the ID to look up
      Returns:
      an Optional containing the Lease if found, or empty otherwise
    • getLeaseCount

      public int getLeaseCount()
      Gets the count of active leases.
      Returns:
      the number of currently tracked leases
    • getAllLeases

      public Map<Long,Lease> getAllLeases()
      Gets an unmodifiable view of all leases.
      Returns:
      map of lease ID to Lease
    • start

      public void start()
      Starts the background expiry monitor thread.

      Creates a virtual thread that runs once per second to check for expired leases and auto-revokes them. Safe to call multiple times (subsequent calls are no-ops if already running).

    • shutdown

      public void shutdown()
      Stops the background expiry monitor thread.

      Waits up to 5 seconds for the monitor thread to terminate. Safe to call even if not running.

    • isRunning

      public boolean isRunning()
      Gets whether the monitor is currently running.
      Returns:
      true if the background monitor is active
    • getLeaseInfo

      public Optional<LeaseManager.LeaseInfo> getLeaseInfo(long leaseId)
      Retrieves information about a lease.
      Parameters:
      leaseId - the ID of the lease
      Returns:
      an Optional containing LeaseInfo if found, or empty otherwise
    • retryPendingRevocation

      public boolean retryPendingRevocation(long leaseId)
      Retry key-expiry callbacks that failed during a prior revoke/expiry operation.
      Parameters:
      leaseId - the revoked/expired lease ID
      Returns:
      true if a pending revocation existed and was retried
    • getPendingRevocations

      public Map<Long, Set<String>> getPendingRevocations()
      Return a dead-letter snapshot of keys whose lease-expiry callbacks still need retry.