Interface CoordinationTransport

All Superinterfaces:
AutoCloseable
All Known Implementing Classes:
KafkaCoordinationTransport

public interface CoordinationTransport extends AutoCloseable
The seam between the succession rules and the cluster.

This interface holds every cluster operation that the coordination rules need, and it holds nothing else. The rules decide who registers, who challenges, and when. This interface carries those decisions to the brokers. KafkaCoordinationTransport is the implementation that talks to a cluster, and a test supplies its own so the rules run with no broker.

Which calls carry authority

acquireEpoch(Role) and writeLease(Role, FencingToken, Lease) are the guarded pair. The first mints the epoch of the role and fences the member that held it before. The second writes under that epoch, and the broker rejects the write when a later member has taken the role. A deposed holder learns that it lost the role from FencedException, and from nothing else.

register(Role, MemberId, long) carries no authority. A candidate holds no epoch when it announces itself, so the registration is a plain append. readRoleRecords(Role) and describe(Role) only read.

Example

transport.register(role, me, clock.nowMillis());
RoleState state = RoleState.fromRecords(role, transport.readRoleRecords(role));
if (Succession.evaluate(state, me, now, config).action() == Decision.Action.CHALLENGE) {
    FencingToken token = transport.acquireEpoch(role);
    transport.writeLease(role, token, config.grant(me, token, now));
}
  • Method Details

    • acquireEpoch

      FencingToken acquireEpoch(Role role)
      Mints a new epoch for a role and fences the member that held it.

      The implementation calls InitProducerId with transactional.id = <role>, and it keeps the producer that the epoch binds, because writeLease(Role, FencingToken, Lease) writes through that producer. The transaction coordinator picks the epoch, so the quorum mints the value and the value only grows.

      Parameters:
      role - the role to take
      Returns:
      the token the transaction coordinator minted
      Throws:
      CoordinationException - if the coordinator refuses the call or the connection fails
    • readRoleRecords

      List<CoordinationEntry> readRoleRecords(Role role)
      Reads the whole partition of a role and returns the records in offset order.

      The read takes committed records only, so an aborted lease write stays invisible. The result holds the records of this role and drops every record of another role that shares the partition.

      Parameters:
      role - the role to read
      Returns:
      the decoded records, oldest first
      Throws:
      CoordinationException - if a fetch fails or a record does not decode
    • register

      void register(Role role, MemberId member, long registeredAtMillis)
      Appends the registration of one member to the partition of a role.

      A candidate holds no epoch, so this append sits outside a transaction and carries no authority. Its offset is the join sequence that the succession rules rank on.

      The caller passes the instant, so the record carries the clock of the member and this interface needs no clock of its own.

      Parameters:
      role - the role the member competes for
      member - the member that announces itself
      registeredAtMillis - the instant of the registration, in milliseconds since the Unix epoch
      Throws:
      CoordinationException - if the append fails
    • writeLease

      void writeLease(Role role, FencingToken token, Lease lease)
      Writes the lease of a role in a transaction under one token.

      The broker rejects the write when a later member has taken the role, and that rejection is how a deposed holder learns it lost the role.

      Parameters:
      role - the role the lease belongs to
      token - the token this transport minted for the role
      lease - the lease record to write
      Throws:
      FencedException - if the broker rejects the token
      CoordinationException - if this transport never minted the token, or if the write fails for another reason
    • clearLease

      void clearLease(Role role, FencingToken token)
      Clears the lease of a role with a tombstone, in a transaction under one token.

      A member writes this when it resigns. A standby then challenges at once rather than at the deadline of the record the member left behind.

      Parameters:
      role - the role to release
      token - the token this transport minted for the role
      Throws:
      FencedException - if the broker rejects the token
      CoordinationException - if this transport never minted the token, or if the write fails for another reason
    • describe

      Optional<FencingToken> describe(Role role)
      Asks the transaction coordinator which token holds a role now.

      A third party calls this to check the authority of a writer. The call joins no group and it takes no epoch.

      Parameters:
      role - the role to look up
      Returns:
      the current token, and empty when no member has ever taken the role
      Throws:
      CoordinationException - if the coordinator lookup fails
    • close

      void close()
      Releases the resources this transport created.

      A transport closes the producers it built for itself. It does not close a client that the caller passed in.

      Specified by:
      close in interface AutoCloseable