2020-10-14 01:38:44 +02:00
|
|
|
package it.tdlight.tdlibsession.td.middle.direct;
|
|
|
|
|
|
|
|
import static it.tdlight.tdlibsession.td.middle.server.AsyncTdMiddleEventBusServer.WAIT_DURATION;
|
|
|
|
|
|
|
|
import io.vertx.core.AbstractVerticle;
|
|
|
|
import io.vertx.core.Promise;
|
|
|
|
import io.vertx.core.json.JsonObject;
|
2020-10-28 12:04:42 +01:00
|
|
|
import it.tdlight.jni.TdApi;
|
2020-10-14 01:38:44 +02:00
|
|
|
import it.tdlight.jni.TdApi.Function;
|
|
|
|
import it.tdlight.jni.TdApi.Object;
|
|
|
|
import it.tdlight.tdlibsession.td.ResponseError;
|
|
|
|
import it.tdlight.tdlibsession.td.TdResult;
|
|
|
|
import it.tdlight.tdlibsession.td.direct.AsyncTdDirectImpl;
|
|
|
|
import it.tdlight.tdlibsession.td.middle.AsyncTdMiddle;
|
|
|
|
import it.tdlight.tdlibsession.td.middle.TdClusterManager;
|
|
|
|
import it.tdlight.utils.MonoUtils;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import org.warp.commonutils.error.InitializationException;
|
|
|
|
import reactor.core.publisher.Flux;
|
|
|
|
import reactor.core.publisher.Mono;
|
|
|
|
import reactor.core.publisher.ReplayProcessor;
|
|
|
|
|
|
|
|
public class AsyncTdMiddleDirect extends AbstractVerticle implements AsyncTdMiddle {
|
|
|
|
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(AsyncTdMiddleDirect.class);
|
|
|
|
|
|
|
|
protected final ReplayProcessor<Boolean> tdClosed = ReplayProcessor.cacheLastOrDefault(false);
|
|
|
|
protected AsyncTdDirectImpl td;
|
|
|
|
private String botAddress;
|
|
|
|
private String botAlias;
|
2020-10-28 12:04:42 +01:00
|
|
|
private Flux<TdApi.Object> updatesFluxCo;
|
2020-10-14 01:38:44 +02:00
|
|
|
|
|
|
|
public AsyncTdMiddleDirect() {
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Mono<AsyncTdMiddleDirect> getAndDeployInstance(TdClusterManager clusterManager,
|
|
|
|
String botAlias,
|
|
|
|
String botAddress) throws InitializationException {
|
|
|
|
try {
|
|
|
|
var instance = new AsyncTdMiddleDirect();
|
2020-10-19 00:50:27 +02:00
|
|
|
var options = clusterManager.newDeploymentOpts().setConfig(new JsonObject()
|
2020-10-14 01:38:44 +02:00
|
|
|
.put("botAlias", botAlias)
|
|
|
|
.put("botAddress", botAddress));
|
|
|
|
return MonoUtils.<String>executeAsFuture(promise -> {
|
|
|
|
clusterManager.getVertx().deployVerticle(instance, options, promise);
|
|
|
|
}).doOnNext(_v -> {
|
|
|
|
logger.trace("Deployed verticle for bot " + botAlias + ", address: " + botAddress);
|
|
|
|
}).thenReturn(instance);
|
|
|
|
} catch (RuntimeException e) {
|
|
|
|
throw new InitializationException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void start(Promise<Void> startPromise) {
|
|
|
|
var botAddress = config().getString("botAddress");
|
|
|
|
if (botAddress == null || botAddress.isEmpty()) {
|
|
|
|
throw new IllegalArgumentException("botAddress is not set!");
|
|
|
|
}
|
|
|
|
this.botAddress = botAddress;
|
|
|
|
var botAlias = config().getString("botAlias");
|
|
|
|
if (botAlias == null || botAlias.isEmpty()) {
|
|
|
|
throw new IllegalArgumentException("botAlias is not set!");
|
|
|
|
}
|
|
|
|
this.botAlias = botAlias;
|
|
|
|
|
|
|
|
this.td = new AsyncTdDirectImpl(botAlias);
|
|
|
|
|
2020-10-19 16:23:40 +02:00
|
|
|
td.initializeClient().doOnSuccess(v -> {
|
|
|
|
updatesFluxCo = Mono.from(tdClosed).filter(closed -> !closed).flatMapMany(_x -> td.getUpdates(WAIT_DURATION, 1000).flatMap(result -> {
|
|
|
|
if (result.succeeded()) {
|
|
|
|
if (result.result().succeeded()) {
|
|
|
|
return Mono.just(result.result().result());
|
|
|
|
} else {
|
|
|
|
logger.error("Received an errored update",
|
|
|
|
ResponseError.newResponseError("incoming update", botAlias, result.result().cause())
|
|
|
|
);
|
2020-10-28 12:04:42 +01:00
|
|
|
return Mono.<TdApi.Object>empty();
|
2020-10-19 16:23:40 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
logger.error("Received an errored update", result.cause());
|
2020-10-28 12:04:42 +01:00
|
|
|
return Mono.<TdApi.Object>empty();
|
2020-10-19 16:23:40 +02:00
|
|
|
}
|
|
|
|
})).publish().refCount(1);
|
|
|
|
startPromise.complete();
|
|
|
|
}).subscribe(success -> {
|
2020-10-14 01:38:44 +02:00
|
|
|
}, (ex) -> {
|
|
|
|
logger.error("Failure when starting bot " + botAlias + ", address " + botAddress, ex);
|
|
|
|
startPromise.fail(new InitializationException("Can't connect tdlib middle client to tdlib middle server!"));
|
|
|
|
}, () -> {});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void stop(Promise<Void> stopPromise) {
|
|
|
|
tdClosed.onNext(true);
|
|
|
|
td.destroyClient().onErrorResume(ex -> {
|
|
|
|
logger.error("Can't destroy client", ex);
|
|
|
|
return Mono.empty();
|
|
|
|
}).doOnTerminate(() -> {
|
|
|
|
logger.debug("TdMiddle verticle stopped");
|
|
|
|
}).subscribe(MonoUtils.toSubscriber(stopPromise));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-10-28 12:04:42 +01:00
|
|
|
public Flux<TdApi.Object> getUpdates() {
|
2020-10-19 16:23:40 +02:00
|
|
|
return Flux.from(updatesFluxCo);
|
2020-10-14 01:38:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public <T extends Object> Mono<TdResult<T>> execute(Function requestFunction, boolean executeDirectly) {
|
|
|
|
return td.<T>execute(requestFunction, executeDirectly).onErrorMap(error -> {
|
|
|
|
return ResponseError.newResponseError(
|
|
|
|
requestFunction,
|
|
|
|
botAlias,
|
|
|
|
error
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|