001 002package io.vrap.rmf.base.client.http; 003 004import java.time.Duration; 005import java.util.concurrent.CompletableFuture; 006import java.util.concurrent.ExecutorService; 007import java.util.concurrent.ScheduledExecutorService; 008import java.util.function.Function; 009 010import io.vrap.rmf.base.client.ApiHttpRequest; 011import io.vrap.rmf.base.client.ApiHttpResponse; 012 013import dev.failsafe.Bulkhead; 014import dev.failsafe.Failsafe; 015import dev.failsafe.FailsafeExecutor; 016import dev.failsafe.spi.Scheduler; 017 018/** 019 * Implementation of a Queue to limit the number of concurrent requests handled by the client 020 * 021 * @include.example io.vrap.rmf.base.client.QueueMiddlewareTest#queueConfiguration() 022 */ 023public class QueueMiddleware implements QueueRequestMiddleware, AutoCloseable { 024 025 private final FailsafeExecutor<ApiHttpResponse<byte[]>> failsafeExecutor; 026 027 public QueueMiddleware(final ExecutorService executorService, final int maxConnection, final Duration maxWaitTime) { 028 this(Scheduler.of(executorService), maxConnection, maxWaitTime); 029 } 030 031 public QueueMiddleware(final ScheduledExecutorService executorService, final int maxConnection, 032 final Duration maxWaitTime) { 033 this(Scheduler.of(executorService), maxConnection, maxWaitTime); 034 } 035 036 public QueueMiddleware(final int maxConnection, final Duration maxWaitTime) { 037 this(Scheduler.DEFAULT, maxConnection, maxWaitTime); 038 } 039 040 public QueueMiddleware(final Scheduler scheduler, final int maxConnections, final Duration maxWaitTime) { 041 final Bulkhead<ApiHttpResponse<byte[]>> bulkhead = Bulkhead.<ApiHttpResponse<byte[]>> builder(maxConnections) 042 .withMaxWaitTime(maxWaitTime) 043 .build(); 044 this.failsafeExecutor = Failsafe.with(bulkhead).with(scheduler); 045 } 046 047 @Override 048 public CompletableFuture<ApiHttpResponse<byte[]>> invoke(ApiHttpRequest request, 049 Function<ApiHttpRequest, CompletableFuture<ApiHttpResponse<byte[]>>> next) { 050 return failsafeExecutor.getStageAsync(() -> next.apply(request)); 051 } 052 053 @Override 054 public void close() { 055 } 056}