io.atomix.primitive.operation.OperationType Java Examples

The following examples show how to use io.atomix.primitive.operation.OperationType. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: RaftServiceContext.java    From atomix with Apache License 2.0 6 votes vote down vote up
/**
 * Executes scheduled callbacks based on the provided time.
 */
private void tick(long index, long timestamp) {
  this.currentIndex = index;

  // If the entry timestamp is less than the current state machine timestamp
  // and the delta is not yet set, set the delta and do not change the current timestamp.
  // If the entry timestamp is less than the current state machine timestamp
  // and the delta is set, update the current timestamp to the entry timestamp plus the delta.
  // If the entry timestamp is greater than or equal to the current timestamp, update the current
  // timestamp and reset the delta.
  if (timestamp < currentTimestamp) {
    if (timestampDelta == 0) {
      timestampDelta = currentTimestamp - timestamp;
    } else {
      currentTimestamp = timestamp + timestampDelta;
    }
  } else {
    currentTimestamp = timestamp;
    timestampDelta = 0;
  }

  // Set the current operation type to COMMAND to allow events to be sent.
  setOperation(OperationType.COMMAND);

  service.tick(WallClockTimestamp.from(timestamp));
}
 
Example #2
Source File: RaftSession.java    From atomix with Apache License 2.0 5 votes vote down vote up
@Override
public void publish(PrimitiveEvent event) {
  // Store volatile state in a local variable.
  State state = this.state;

  // If the sessions's state is not active, just ignore the event.
  if (!state.active()) {
    return;
  }

  // If the event is being published during a read operation, throw an exception.
  checkState(context.currentOperation() == OperationType.COMMAND, "session events can only be published during command execution");

  // If the client acked an index greater than the current event sequence number since we know the
  // client must have received it from another server.
  if (completeIndex > context.currentIndex()) {
    return;
  }

  // If no event has been published for this index yet, create a new event holder.
  if (this.currentEventList == null || this.currentEventList.eventIndex != context.currentIndex()) {
    long previousIndex = eventIndex;
    eventIndex = context.currentIndex();
    this.currentEventList = new EventHolder(eventIndex, previousIndex);
  }

  // Add the event to the event holder.
  this.currentEventList.events.add(event);
}
 
Example #3
Source File: PrimaryRole.java    From atomix with Apache License 2.0 5 votes vote down vote up
@Override
public CompletableFuture<ExecuteResponse> execute(ExecuteRequest request) {
  logRequest(request);
  if (request.operation().id().type() == OperationType.COMMAND) {
    return executeCommand(request).thenApply(this::logResponse);
  } else if (request.operation().id().type() == OperationType.QUERY) {
    return executeQuery(request).thenApply(this::logResponse);
  }
  return Futures.exceptionalFuture(new IllegalArgumentException("Unknown operation type"));
}
 
Example #4
Source File: RaftServiceContext.java    From atomix with Apache License 2.0 5 votes vote down vote up
/**
 * Applies a query to the state machine.
 */
private void applyQuery(long timestamp, RaftSession session, PrimitiveOperation operation, CompletableFuture<OperationResult> future) {
  // If the service has been deleted then throw an unknown service exception.
  if (deleted) {
    log.warn("Service {} has been deleted by another process", serviceName);
    future.completeExceptionally(new RaftException.UnknownService("Service " + serviceName + " has been deleted"));
    return;
  }

  // If the session is not open, fail the request.
  if (!session.getState().active()) {
    log.warn("Inactive session: " + session.sessionId());
    future.completeExceptionally(new RaftException.UnknownSession("Unknown session: " + session.sessionId()));
    return;
  }

  // Set the current operation type to QUERY to prevent events from being sent to clients.
  setOperation(OperationType.QUERY);

  Commit<byte[]> commit = new DefaultCommit<>(currentIndex, operation.id(), operation.value(), session, timestamp);

  long eventIndex = session.getEventIndex();

  OperationResult result;
  try {
    currentSession = session;
    result = OperationResult.succeeded(currentIndex, eventIndex, service.apply(commit));
  } catch (Exception e) {
    result = OperationResult.failed(currentIndex, eventIndex, e);
  } finally {
    currentSession = null;
  }
  future.complete(result);
}
 
Example #5
Source File: DefaultServiceExecutor.java    From atomix with Apache License 2.0 5 votes vote down vote up
@Override
public Scheduled schedule(Duration delay, Runnable callback) {
  checkOperation(OperationType.COMMAND, "callbacks can only be scheduled during command execution");
  checkArgument(!delay.isNegative(), "delay cannot be negative");
  checkNotNull(callback, "callback cannot be null");
  log.trace("Scheduled callback {} with delay {}", callback, delay);
  return new ScheduledTask(callback, delay.toMillis()).schedule();
}
 
Example #6
Source File: DefaultServiceExecutor.java    From atomix with Apache License 2.0 5 votes vote down vote up
@Override
public Scheduled schedule(Duration initialDelay, Duration interval, Runnable callback) {
  checkOperation(OperationType.COMMAND, "callbacks can only be scheduled during command execution");
  checkArgument(!initialDelay.isNegative(), "initialDelay cannot be negative");
  checkArgument(!interval.isNegative(), "interval cannot be negative");
  checkNotNull(callback, "callback cannot be null");
  log.trace("Scheduled repeating callback {} with initial delay {} and interval {}", callback, initialDelay, interval);
  return new ScheduledTask(callback, initialDelay.toMillis(), interval.toMillis()).schedule();
}
 
Example #7
Source File: DefaultServiceExecutorTest.java    From atomix with Apache License 2.0 5 votes vote down vote up
private ServiceExecutor executor() {
  ServiceContext context = mock(ServiceContext.class);
  when(context.serviceId()).thenReturn(PrimitiveId.from(1));
  when(context.serviceType()).thenReturn(TestPrimitiveType.instance());
  when(context.serviceName()).thenReturn("test");
  when(context.currentOperation()).thenReturn(OperationType.COMMAND);
  return new DefaultServiceExecutor(context, Serializer.using(Namespaces.BASIC));
}
 
Example #8
Source File: PrimaryBackupServiceContext.java    From atomix with Apache License 2.0 5 votes vote down vote up
/**
 * Resets the current index to the given index and timestamp.
 *
 * @param index     the index to which to reset the current index
 * @param timestamp the timestamp to which to reset the current timestamp
 */
public void resetIndex(long index, long timestamp) {
  currentOperation = OperationType.COMMAND;
  operationIndex = index;
  currentIndex = index;
  currentTimestamp = timestamp;
  setCommitIndex(index);
  service.tick(new WallClockTimestamp(currentTimestamp));
}
 
Example #9
Source File: PrimaryBackupServiceContext.java    From atomix with Apache License 2.0 5 votes vote down vote up
/**
 * Increments the current index and returns true if the given index is the next index.
 *
 * @param index the index to which to increment the current index
 * @return indicates whether the current index was successfully incremented
 */
public boolean nextIndex(long index) {
  if (operationIndex + 1 == index) {
    currentOperation = OperationType.COMMAND;
    operationIndex++;
    return true;
  }
  return false;
}
 
Example #10
Source File: AtomicSemaphoreService.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Operation(value = "increase", type = OperationType.COMMAND)
int increase(int permits);
 
Example #11
Source File: AtomicSemaphoreService.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Operation(value = "acquire", type = OperationType.COMMAND)
void acquire(long id, int permits, long timeout);
 
Example #12
Source File: AtomicSemaphoreService.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Operation(value = "release", type = OperationType.COMMAND)
void release(int permits);
 
Example #13
Source File: AtomicSemaphoreService.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Operation(value = "drain", type = OperationType.COMMAND)
int drain();
 
Example #14
Source File: PrimaryBackupServiceContext.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Override
public OperationType currentOperation() {
  return currentOperation;
}
 
Example #15
Source File: AtomicSemaphoreService.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Operation(value = "reduce", type = OperationType.COMMAND)
int reduce(int permits);
 
Example #16
Source File: AtomicSemaphoreService.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Operation(value = "available", type = OperationType.QUERY)
int available();
 
Example #17
Source File: AtomicSemaphoreService.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Operation(value = "queueStatus", type = OperationType.QUERY)
QueueStatus queueStatus();
 
Example #18
Source File: AtomicSemaphoreService.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Operation(value = "holderStatus", type = OperationType.QUERY)
Map<Long, Integer> holderStatus();
 
Example #19
Source File: DefaultAtomicLockServiceTest.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Test
public void testSnapshot() throws Exception {
  ServiceContext context = mock(ServiceContext.class);
  when(context.serviceType()).thenReturn(LeaderElectionType.instance());
  when(context.serviceName()).thenReturn("test");
  when(context.serviceId()).thenReturn(PrimitiveId.from(1));
  when(context.wallClock()).thenReturn(new WallClock());
  when(context.currentOperation()).thenReturn(OperationType.COMMAND);

  Session session = mock(Session.class);
  when(session.sessionId()).thenReturn(SessionId.from(1));
  when(context.currentSession()).thenReturn(session);

  DefaultAtomicLockService service = new DefaultAtomicLockService();
  service.init(context);
  service.register(session);
  service.tick(new WallClockTimestamp());

  Buffer buffer = HeapBuffer.allocate();
  service.backup(new DefaultBackupOutput(buffer, service.serializer()));

  service = new DefaultAtomicLockService();
  service.init(context);
  service.register(session);
  service.tick(new WallClockTimestamp());
  service.restore(new DefaultBackupInput(buffer.flip(), service.serializer()));

  service.lock(1);
  service.lock(2, 1000);

  buffer = HeapBuffer.allocate();
  service.backup(new DefaultBackupOutput(buffer, service.serializer()));

  service = new DefaultAtomicLockService();
  service.init(context);
  service.register(session);
  service.tick(new WallClockTimestamp());
  service.restore(new DefaultBackupInput(buffer.flip(), service.serializer()));

  assertTrue(service.isLocked(service.lock.index));
  assertTrue(!service.queue.isEmpty());
  assertTrue(!service.timers.isEmpty());
}
 
Example #20
Source File: TestProtocolService.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Override
public OperationType currentOperation() {
  return operationType;
}
 
Example #21
Source File: RaftServiceContext.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Override
public OperationType currentOperation() {
  return currentOperation;
}
 
Example #22
Source File: DefaultOperationId.java    From atomix with Apache License 2.0 4 votes vote down vote up
public DefaultOperationId(String id, OperationType type) {
  super(id);
  this.type = type;
}
 
Example #23
Source File: PrimaryElectorServiceTest.java    From atomix with Apache License 2.0 4 votes vote down vote up
PrimaryElectorService newService() {
  PrimaryElectorService elector = new PrimaryElectorService();
  elector.init(new ServiceContext() {
    @Override
    public PrimitiveId serviceId() {
      return PrimitiveId.from(1L);
    }

    @Override
    public String serviceName() {
      return "test-primary-elector";
    }

    @SuppressWarnings("rawtypes")
    @Override
    public PrimitiveType serviceType() {
      return PrimaryElectorType.instance();
    }

    @Override
    public MemberId localMemberId() {
      return null;
    }

    @Override
    public <C extends ServiceConfig> C serviceConfig() {
      return null;
    }

    @Override
    public long currentIndex() {
      return 0;
    }

    @Override
    public Session<?> currentSession() {
      return null;
    }

    @Override
    public OperationType currentOperation() {
      return null;
    }

    @Override
    public LogicalClock logicalClock() {
      return null;
    }

    @Override
    public WallClock wallClock() {
      return null;
    }
  });
  elector.tick(WallClockTimestamp.from(System.currentTimeMillis()));
  return elector;
}
 
Example #24
Source File: DefaultServiceExecutor.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Override
public void execute(Runnable callback) {
  checkOperation(OperationType.COMMAND, "callbacks can only be scheduled during command execution");
  checkNotNull(callback, "callback cannot be null");
  tasks.add(callback);
}
 
Example #25
Source File: LogProxySession.java    From atomix with Apache License 2.0 4 votes vote down vote up
@Override
public OperationType currentOperation() {
  return currentOperation;
}
 
Example #26
Source File: LogProxySession.java    From atomix with Apache License 2.0 4 votes vote down vote up
/**
 * Consumes a record from the log.
 *
 * @param record the record to consume
 */
@SuppressWarnings("unchecked")
private void consume(LogRecord record) {
  // Decode the raw log operation from the record.
  LogOperation operation = decodeInternal(record.value());

  // If this operation is not destined for this primitive, ignore it.
  // TODO: If multiple primitives of different types are created and destroyed on the same distributed log,
  // we need to be able to differentiate between different instances of a service by the service ID.
  if (!operation.primitive().equals(name())) {
    return;
  }

  // Create a session from the log record.
  Session session = getOrCreateSession(operation.sessionId());

  // Update the local context for the service.
  currentIndex = record.index();
  currentSession = session;
  currentOperation = operation.operationId().type();
  currentTimestamp = record.timestamp();

  // Apply the operation to the service.
  byte[] output = service.apply(new DefaultCommit<>(
      currentIndex,
      operation.operationId(),
      operation.operation(),
      currentSession,
      currentTimestamp));

  // If the operation session matches the local session, complete the write future.
  if (operation.sessionId().equals(this.session.sessionId())) {
    CompletableFuture future = writeFutures.remove(operation.operationIndex());
    if (future != null) {
      future.complete(decode(output));
    }
  }

  // Iterate through pending reads and complete any reads at indexes less than or equal to the applied index.
  PendingRead pendingRead = pendingReads.peek();
  while (pendingRead != null && pendingRead.index <= record.index()) {
    session = getOrCreateSession(this.session.sessionId());
    currentSession = session;
    currentOperation = OperationType.QUERY;
    try {
      output = service.apply(new DefaultCommit<>(
          currentIndex,
          pendingRead.operationId,
          pendingRead.bytes,
          session,
          currentTimestamp));
      pendingRead.future.complete(output);
    } catch (Exception e) {
      pendingRead.future.completeExceptionally(new PrimitiveException.ServiceException());
    }
    pendingReads.remove();
    pendingRead = pendingReads.peek();
  }
}
 
Example #27
Source File: RaftServiceContext.java    From atomix with Apache License 2.0 2 votes vote down vote up
/**
 * Sets the current state machine operation type.
 *
 * @param operation the current state machine operation type
 */
private void setOperation(OperationType operation) {
  this.currentOperation = operation;
}
 
Example #28
Source File: PrimaryBackupServiceContext.java    From atomix with Apache License 2.0 2 votes vote down vote up
/**
 * Returns the current service index and sets the service to read-only mode.
 *
 * @return the current index
 */
public long getIndex() {
  currentOperation = OperationType.QUERY;
  return currentIndex;
}
 
Example #29
Source File: PrimaryBackupServiceContext.java    From atomix with Apache License 2.0 2 votes vote down vote up
/**
 * Sets the current index.
 *
 * @param index the current index.
 * @return the current index
 */
public long setIndex(long index) {
  currentOperation = OperationType.COMMAND;
  currentIndex = index;
  return currentIndex;
}
 
Example #30
Source File: PrimaryBackupServiceContext.java    From atomix with Apache License 2.0 2 votes vote down vote up
/**
 * Increments and returns the next service index.
 *
 * @return the next index
 */
public long nextIndex() {
  currentOperation = OperationType.COMMAND;
  return ++operationIndex;
}