package net.horizoncode.tickettest.manager; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import lombok.Builder; import lombok.Getter; import net.horizoncode.tickettest.TicketTest; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @Builder( toBuilder = true, builderClassName = "InternalTicketManagerBuilder", builderMethodName = "internalBuilder") @Getter public class TicketManager { private ListeningExecutorService service; private Set ticketSet; private int maxTicketsExisting; private long ticketLifespan; public Ticket addTicket(Runnable onExpire) { ListenableFuture asyncTask = service.submit( () -> { if (waitForFreeTicket()) TicketTest.getInstance().getLogger().warning("max amount of tickets reached, waiting..."); while (waitForFreeTicket()) { TimeUnit.MILLISECONDS.sleep(1); } Ticket t = Ticket.builder().timeTicketCreated(ticketLifespan).onExpire(onExpire).ticketManager(this).build(); TicketTest.getInstance().getLogger().info("Got ticket with UUID: " + t.getTicketID()); return t; }); try { return asyncTask.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); return null; } } private boolean waitForFreeTicket() { return ticketSet.size() >= maxTicketsExisting; } void init() { service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)); ticketSet = new HashSet<>(); } public static Builder builder() { return new Builder(); } public static class Builder extends InternalTicketManagerBuilder { Builder() { super(); } @Override public TicketManager build() { TicketManager ticketManager = super.build(); ticketManager.init(); return ticketManager; } } }