DefaultEventExecutor.java
package com.github.jonasrutishauser.transactional.event.core.concurrent;
import java.time.Instant;
import java.util.Date;
import java.util.concurrent.ScheduledFuture;
import java.util.function.Consumer;
import java.util.function.LongSupplier;
import com.github.jonasrutishauser.transactional.event.api.Events;
import jakarta.enterprise.concurrent.ContextService;
import jakarta.enterprise.concurrent.LastExecution;
import jakarta.enterprise.concurrent.ManagedScheduledExecutorService;
import jakarta.enterprise.concurrent.Trigger;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@ApplicationScoped
public class DefaultEventExecutor implements EventExecutor {
private final ManagedScheduledExecutorService executor;
private final ContextService contextService;
private InContextWrapper wrapper = InContextWrapper.DEFAULT;
DefaultEventExecutor() {
this(null, null);
}
@Inject
DefaultEventExecutor(@Events ManagedScheduledExecutorService executor, @Events ContextService contextService) {
this.executor = executor;
this.contextService = contextService;
}
@Override
public void execute(Runnable command) {
executor.execute(() -> wrapper.accept(command));
}
@Override
public Task schedule(Runnable command, LongSupplier interval) {
wrapper = contextService.createContextualProxy(InContextWrapper.DEFAULT, InContextWrapper.class);
ScheduledFuture<?> future = executor.schedule(command, new Trigger() {
@Override
public boolean skipRun(LastExecution lastExecutionInfo, Date scheduledRunTime) {
return false;
}
@Override
public Date getNextRunTime(LastExecution lastExecutionInfo, Date taskScheduledTime) {
return Date.from(Instant.now().plusMillis(interval.getAsLong()));
}
});
return () -> future.cancel(false);
}
public interface InContextWrapper extends Consumer<Runnable> {
InContextWrapper DEFAULT = Runnable::run;
}
}