Interface ServiceExecutor

All Superinterfaces:
Executor, io.atomix.utils.concurrent.Scheduler

public interface ServiceExecutor
extends Executor, io.atomix.utils.concurrent.Scheduler
Facilitates registration and execution of state machine commands and provides deterministic scheduling.

The state machine executor is responsible for managing input to and output from a PrimitiveService. As operations are committed to the Raft log, the executor is responsible for applying them to the state machine. commands are guaranteed to be applied to the state machine in the order in which they appear in the Raft log and always in the same thread, so state machines don't have to be thread safe. queries are not generally written to the Raft log and will instead be applied according to their Consistency.

State machines can use the executor to provide deterministic scheduling during the execution of command callbacks.

   
   private Object putWithTtl(Commit<PutWithTtl> commit) {
     map.put(commit.operation().key(), commit);
     executor.schedule(Duration.ofMillis(commit.operation().ttl()), () -> {
       map.remove(commit.operation().key()).close();
     });
   }
   
 
As with all state machine callbacks, the executor will ensure scheduled callbacks are executed sequentially and deterministically. As long as state machines schedule callbacks deterministically, callbacks will be executed deterministically. Internally, the state machine executor triggers callbacks based on various timestamps in the Raft log. This means the scheduler is dependent on internal or user-defined operations being written to the log. Prior to the execution of a command, any expired scheduled callbacks will be executed based on the command's logged timestamp.

It's important to note that callbacks can only be scheduled during PrimitiveOperation operations or by recursive scheduling. If a state machine attempts to schedule a callback via the executor during the execution of a query, a IllegalStateException will be thrown. This is because queries are usually only applied on a single state machine within the cluster, and so scheduling callbacks in reaction to query execution would not be deterministic.

See Also:
PrimitiveService, ServiceContext
  • Method Summary

    Modifier and Type Method Description
    byte[] apply​(Commit<byte[]> commit)
    Applies the given commit to the executor.
    void handle​(OperationId operationId, java.util.function.Function<Commit<byte[]>,​byte[]> callback)
    Registers a operation callback.
    default void register​(OperationId operationId, Runnable callback)
    Registers a operation callback.
    <T> void register​(OperationId operationId, java.util.function.Consumer<Commit<T>> callback)
    Registers a operation callback.
    <T,​ R> void register​(OperationId operationId, java.util.function.Function<Commit<T>,​R> callback)
    Registers an operation callback.
    <R> void register​(OperationId operationId, java.util.function.Supplier<R> callback)
    Registers a no argument operation callback.
    void tick​(io.atomix.utils.time.WallClockTimestamp timestamp)
    Increments the service clock.

    Methods inherited from interface java.util.concurrent.Executor

    execute

    Methods inherited from interface io.atomix.utils.concurrent.Scheduler

    schedule, schedule, schedule, schedule
  • Method Details

    • tick

      void tick​(io.atomix.utils.time.WallClockTimestamp timestamp)
      Increments the service clock.
      Parameters:
      timestamp - the wall clock timestamp
    • apply

      byte[] apply​(Commit<byte[]> commit)
      Applies the given commit to the executor.
      Parameters:
      commit - the commit to apply
      Returns:
      the commit result
    • handle

      void handle​(OperationId operationId, java.util.function.Function<Commit<byte[]>,​byte[]> callback)
      Registers a operation callback.
      Parameters:
      operationId - the operation identifier
      callback - the operation callback
      Throws:
      NullPointerException - if the operationId or callback is null
    • register

      default void register​(OperationId operationId, Runnable callback)
      Registers a operation callback.
      Parameters:
      operationId - the operation identifier
      callback - the operation callback
      Throws:
      NullPointerException - if the operationId or callback is null
    • register

      <R> void register​(OperationId operationId, java.util.function.Supplier<R> callback)
      Registers a no argument operation callback.
      Parameters:
      operationId - the operation identifier
      callback - the operation callback
      Throws:
      NullPointerException - if the operationId or callback is null
    • register

      <T> void register​(OperationId operationId, java.util.function.Consumer<Commit<T>> callback)
      Registers a operation callback.
      Parameters:
      operationId - the operation identifier
      callback - the operation callback
      Throws:
      NullPointerException - if the operationId or callback is null
    • register

      <T,​ R> void register​(OperationId operationId, java.util.function.Function<Commit<T>,​R> callback)
      Registers an operation callback.
      Parameters:
      operationId - the operation identifier
      callback - the operation callback
      Throws:
      NullPointerException - if the operationId or callback is null