Skip to content

Instantly share code, notes, and snippets.

@jinwik
Last active February 7, 2022 02:23
Show Gist options
  • Save jinwik/555315e24bdf187d9a93b6366b600f8b to your computer and use it in GitHub Desktop.
Save jinwik/555315e24bdf187d9a93b6366b600f8b to your computer and use it in GitHub Desktop.
package dev.failsafe.examples;
import dev.failsafe.Failsafe;
import dev.failsafe.FailsafeExecutor;
import dev.failsafe.RateLimiter;
import dev.failsafe.spi.DefaultScheduledFuture;
import dev.failsafe.spi.Scheduler;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServerRequest;
import java.time.Duration;
/**
* @author jinweikang
*/
public class VertxHttpServer extends AbstractVerticle {
private FailsafeExecutor<Object> failsafeExecutor;
@Override
public void start() {
init();
vertx.createHttpServer()
.requestHandler(this::requestHandler)
.listen(8080);
}
private void requestHandler(HttpServerRequest httpServerRequest) {
failsafeExecutor.getAsyncExecution(execution -> {
asyncCall().onSuccess(v -> {
// how can I get the delay time of the rate limiter if a delay occurred?
httpServerRequest.response().putHeader("delay", "null");
httpServerRequest.response().end("Hello World");
});
}).exceptionally(e -> {
httpServerRequest.response().setStatusCode(429).end();
return null;
});
}
private Future<Void> asyncCall() {
Promise<Void> promise = Promise.promise();
vertx.setTimer(1, id -> {
promise.complete();
});
return promise.future();
}
private void init() {
RateLimiter<Object> rateLimiter = RateLimiter
.smoothBuilder(1, Duration.ofSeconds(1))
.withMaxWaitTime(Duration.ofSeconds(10)).build();
Scheduler scheduler = (callable, delay, unit) -> {
Runnable runnable = () -> {
try {
callable.call();
} catch (Exception e) {
}
};
long timerId = -1;
if (delay == 0) {
vertx.getOrCreateContext().runOnContext(v -> {
runnable.run();
});
} else {
System.out.println("delay: " + delay);
timerId = vertx.setTimer(unit.toMillis(delay), id -> {
runnable.run();
});
};
return new VertxScheduledFuture(vertx, timerId);
};
failsafeExecutor = Failsafe.with(rateLimiter)
.with(scheduler);
}
private class VertxScheduledFuture extends DefaultScheduledFuture<Object> {
private final Vertx vertx;
private long timerId = -1;
public VertxScheduledFuture(Vertx vertx, long timerId) {
this.vertx = vertx;
this.timerId = timerId;
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return timerId != -1 && vertx.cancelTimer(timerId);
}
}
public static void main(String[] args) {
Vertx.vertx().deployVerticle(new VertxHttpServer());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment