@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); }
@Override public <T> void register(OperationId operationId, Consumer<Commit<T>> callback) { checkNotNull(operationId, "operationId cannot be null"); checkNotNull(callback, "callback cannot be null"); handle(operationId, commit -> { callback.accept(commit.map(this::decode)); return null; }); }
@Override public byte[] apply(Commit<byte[]> commit) { log.trace("Executing {}", commit); this.operationType = commit.operation().type(); this.timestamp = commit.wallClockTime().unixTimestamp(); // Look up the registered callback for the operation. Function<Commit<byte[]>, byte[]> operation = operations.get(commit.operation().id()); if (operation == null) { throw new IllegalStateException("Unknown state machine operation: " + commit.operation()); } else { // Execute the operation. If the operation return value is a Future, await the result, // otherwise immediately complete the execution future. try { return operation.apply(commit); } catch (Exception e) { log.warn("State machine operation failed: {}", e.getMessage()); throw new PrimitiveException.ServiceException(e); } finally { runTasks(); } } }
@Override public final void init(ServiceContext context) { this.context = context; this.executor = new DefaultServiceExecutor(context, serializer()); this.log = ContextualLoggerFactory.getLogger(getClass(), LoggerContext.builder(PrimitiveService.class) .addValue(context.serviceId()) .add("type", context.serviceType()) .add("name", context.serviceName()) .build()); configure(executor); }
@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(); }
@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(); }