tdlib-session-container/src/main/java/it/tdlight/reactiveapi/AtomixReactiveApiMultiClient.java

74 lines
2.4 KiB
Java
Raw Normal View History

2022-01-09 20:20:20 +01:00
package it.tdlight.reactiveapi;
import io.atomix.cluster.messaging.ClusterEventService;
import io.atomix.cluster.messaging.MessagingException;
import io.atomix.cluster.messaging.Subscription;
import it.tdlight.jni.TdApi;
import it.tdlight.reactiveapi.Event.ClientBoundEvent;
import it.tdlight.reactiveapi.Event.Request;
import java.time.Duration;
import java.time.Instant;
2022-01-11 01:45:39 +01:00
import java.util.List;
2022-01-09 20:20:20 +01:00
import java.util.concurrent.CompletableFuture;
import reactor.core.publisher.BufferOverflowStrategy;
import reactor.core.publisher.Flux;
import reactor.core.publisher.FluxSink.OverflowStrategy;
import reactor.core.publisher.Mono;
2022-01-11 19:59:27 +01:00
import reactor.core.scheduler.Schedulers;
2022-01-09 20:20:20 +01:00
public class AtomixReactiveApiMultiClient implements ReactiveApiMultiClient, AutoCloseable {
private final ClusterEventService eventService;
2022-01-13 01:59:26 +01:00
private final KafkaConsumer kafkaConsumer;
2022-01-13 16:19:10 +01:00
private final String subGroupId;
2022-01-09 20:20:20 +01:00
2022-01-09 20:50:58 +01:00
private volatile boolean closed = false;
2022-01-13 16:19:10 +01:00
AtomixReactiveApiMultiClient(AtomixReactiveApi api, KafkaConsumer kafkaConsumer, String subGroupId) {
2022-01-09 20:20:20 +01:00
this.eventService = api.getAtomix().getEventService();
2022-01-13 01:59:26 +01:00
this.kafkaConsumer = kafkaConsumer;
2022-01-13 16:19:10 +01:00
this.subGroupId = subGroupId;
2022-01-09 20:20:20 +01:00
}
@Override
2022-01-13 01:59:26 +01:00
public Flux<ClientBoundEvent> clientBoundEvents(boolean ack) {
if (closed) {
return Flux.empty();
}
2022-01-13 16:19:10 +01:00
return kafkaConsumer.consumeMessages(subGroupId, ack).takeUntil(s -> closed);
2022-01-09 20:20:20 +01:00
}
@Override
public <T extends TdApi.Object> Mono<T> request(long userId, long liveId, TdApi.Function<T> request, Instant timeout) {
2022-01-09 20:50:58 +01:00
return Mono.fromCompletionStage(() -> {
if (closed) {
return CompletableFuture.failedFuture(new TdError(500, "Session is closed"));
}
return eventService.send("session-" + liveId + "-requests",
new Request<>(liveId, request, timeout),
LiveAtomixReactiveApiClient::serializeRequest,
LiveAtomixReactiveApiClient::deserializeResponse,
Duration.between(Instant.now(), timeout)
);
2022-01-11 19:59:27 +01:00
}).subscribeOn(Schedulers.boundedElastic()).<T>handle((item, sink) -> {
2022-01-09 20:50:58 +01:00
if (item instanceof TdApi.Error error) {
sink.error(new TdError(error.code, error.message));
} else {
//noinspection unchecked
sink.next((T) item);
}
}).onErrorMap(ex -> {
if (ex instanceof MessagingException.NoRemoteHandler) {
return new TdError(404, "Bot #IDU" + userId + " (live id: " + liveId + ") is not found on the cluster");
} else {
return ex;
}
});
2022-01-09 20:20:20 +01:00
}
@Override
public void close() {
2022-01-09 20:50:58 +01:00
closed = true;
2022-01-09 20:20:20 +01:00
}
}