Class JdbcMachineLeaseStore

java.lang.Object
me.ahoo.cosid.jdbc.JdbcMachineLeaseStore
All Implemented Interfaces:
MachineLeaseStore

public class JdbcMachineLeaseStore extends Object implements MachineLeaseStore
MachineLeaseStore on the cosid_machine table, with conditional updates on (instance_id, last_timestamp) as the compare-and-set.

It uses the same rows as the 3.4 machine id distributor (a released machine id has an empty instance_id), so instances running either one, and 3.4 instances, can share a namespace during an upgrade. The lease keeps its renewal time, watermark and version in the renew_time, watermark and lease_version columns, and last_timestamp holds a value that is at least all of them and strictly increases, which 3.4 reads as its last timestamp and which is the lease version. lease_version equals last_timestamp when this store wrote the row last; otherwise a 3.4 instance did, and last_timestamp stands for the renewal time and the watermark. A 3.4 instance can write back the same last_timestamp (a host clock behind it), so handing a machine id to someone else never relies on the lease columns alone: expiry is judged on last_timestamp, exactly as 3.4 judges it, and a new owner starts after it. The table needs the stable column (ADD_STABLE_COLUMN_SQL) and the lease columns (ADD_LEASE_COLUMNS_SQL, PostgreSqlDialect.ADD_LEASE_COLUMNS_SQL): the constructor fails naming the statement when they are missing. The server clock is read with serverTimeSql: MYSQL_SERVER_TIME_SQL by default, PostgreSqlDialect.SERVER_TIME_SQL for PostgreSQL. Every statement has the query timeout, and writes are committed when the connection is not in auto-commit mode.

Since:
3.4.0
  • Field Details

    • MYSQL_SERVER_TIME_SQL

      public static final String MYSQL_SERVER_TIME_SQL
      Current time of a MySQL server in milliseconds.

      unix_timestamp() without an argument does not go through the session time zone: unix_timestamp(now(3)) does, and returns a time one hour too low during the repeated hour at the end of daylight saving time.

      See Also:
    • ADD_STABLE_COLUMN_SQL

      public static final String ADD_STABLE_COLUMN_SQL
      Migration of a table created before the stable column existed (MySQL syntax).
      See Also:
    • ADD_LEASE_COLUMNS_SQL

      public static final String ADD_LEASE_COLUMNS_SQL
      Migration of a cosid_machine table created before 4.0 (MySQL syntax).
      See Also:
  • Constructor Details

    • JdbcMachineLeaseStore

      public JdbcMachineLeaseStore(DataSource dataSource)
    • JdbcMachineLeaseStore

      public JdbcMachineLeaseStore(DataSource dataSource, Duration queryTimeout, String serverTimeSql)
      Create a JDBC lease store.
      Parameters:
      queryTimeout - timeout applied to each statement, null or zero means no timeout
      serverTimeSql - a query returning the database server's current time in milliseconds
  • Method Details

    • claimSelf

      public Optional<Lease> claimSelf(String namespace, InstanceId instanceId, long now)
      Description copied from interface: MachineLeaseStore
      Take back the lease this instance already holds, renewing it to now, whether or not it has expired. The watermark is raised to at least now and the stored renewed at.
      Specified by:
      claimSelf in interface MachineLeaseStore
      Returns:
      the renewed lease, or empty if the instance holds none (it was released or recycled)
    • claimReleased

      public Optional<Lease> claimReleased(String namespace, InstanceId instanceId, int maxMachineId, long now)
      Description copied from interface: MachineLeaseStore
      Take a machine id that a non-stable instance released on shutdown.
      Specified by:
      claimReleased in interface MachineLeaseStore
      maxMachineId - the largest machine id allowed: released ids above it (left over from a larger machine bit) are never returned
      Returns:
      the new lease, or empty if no released machine id up to maxMachineId is left
    • claimExpired

      public Optional<Lease> claimExpired(String namespace, InstanceId instanceId, int maxMachineId, long expiredBefore, long now)
      Description copied from interface: MachineLeaseStore
      Take over a machine id whose owner has not renewed it since expiredBefore. Leases of stable instances are never taken over.
      Specified by:
      claimExpired in interface MachineLeaseStore
      maxMachineId - the largest machine id allowed: expired ids above it are never returned
      expiredBefore - leases renewed at or before this time are expired
      Returns:
      the new lease, or empty if no lease up to maxMachineId has expired
    • claimNew

      public Optional<Lease> claimNew(String namespace, InstanceId instanceId, int maxMachineId, long now)
      Description copied from interface: MachineLeaseStore
      Take the next machine id that was never used in the namespace.
      Specified by:
      claimNew in interface MachineLeaseStore
      maxMachineId - the largest machine id allowed
      Returns:
      the new lease, or empty if every machine id up to maxMachineId is in use
    • renew

      public Optional<Lease> renew(Lease lease, long now)
      Description copied from interface: MachineLeaseStore
      Renew a lease to now if it is still the current version, even when now is before the stored renewed at (the store clock moved back). The watermark is unchanged.
      Specified by:
      renew in interface MachineLeaseStore
      Returns:
      the renewed lease, or empty if the lease was taken over, released or changed since
    • release

      public boolean release(Lease lease, long watermark)
      Description copied from interface: MachineLeaseStore
      Release a lease on shutdown, if it is still the current version. A stable instance keeps its machine id (only the watermark is updated); otherwise the machine id becomes available to MachineLeaseStore.claimReleased(java.lang.String, me.ahoo.cosid.machine.InstanceId, int, long).
      Specified by:
      release in interface MachineLeaseStore
      watermark - the generator's last timestamp: the watermark becomes at least this, so that the next owner waits if its clock is behind
      Returns:
      false if the lease was taken over or changed since
    • serverTime

      public long serverTime()
      The database server's clock, read with serverTimeSql.
      Specified by:
      serverTime in interface MachineLeaseStore