I made Async CompletableFuture so that I would first make a payment and then sleep for 10 minutes. And this was repeated endlessly. But sleep once doesn’t work anymore
public class PaymentWorker implements Callable<AutoPayResult> {
private boolean isActive;
private UUID workerId;
@Override
public AutoPayResultV2 call() {
// toDo something pay method
}
public void stopWorker() {
isActive = false;
}
}
@Service
@Slf4j
@RequiredArgsConstructor
public class AutoPaymentServiceV2Impl implements AutoPaymentServiceV2 {
private final List<PaymentWorkerV2> workers = new ArrayList<>();
private volatile boolean isActive = false;
private void runProcess(PaymentWorker z) {
log.info("Starting worker with id: {}", z.getWorkerId());
CompletableFuture
.supplyAsync(
z::call
)
.thenApplyAsync(s -> {
stopWorkerById(z);
return s;
}
)
.thenAcceptAsync(d -> {
if (isActive) {
var pw = new PaymentWorker(
isActive,
UUID.randomUUID()
);
workers.add(pw);
sleepAfterFinishWorker(pw.getBranch());
runProcess(pw);
} else {
log.warn("Auto payment V2 is not active and will be stopped");
}
}
);
}
private void stopWorkerById(PaymentWorkerV2 paymentWorkerV2) {
log.info("Stop workerwith id: {}", paymentWorkerV2.getWorkerId());
workers
.stream()
.filter(z -> z.getWorkerId().equals(paymentWorkerV2.getWorkerId()))
.findFirst()
.ifPresent(w -> {
log.info("Worker found for removing");
if (w.isActive())
w.stopWorker();
workers.remove(w);
}
);
}
private void sleepAfterFinishWorker(String branch) {
var seconds = 1000 * 60;
log.info("Sleep worker after finishing for: {} seconds", seconds);
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(seconds));
}
}
The logic is this:
First it takes “worker” and then makes a payment using the call method. After completion, it removes this “worker” from the list so that it cannot be processed again. Then it sleeps for 60 seconds. Then it creates a new “worker” again and does the same thing again.
All processes should be asynchronous, creating a separate thread