reworked MessageBroker, now also with in-memory implementation

This commit is contained in:
kento2 2026-07-07 15:05:36 +02:00
parent d9baa4113e
commit 7e5bd1bb6d
15 changed files with 249 additions and 157 deletions

View file

@ -26,7 +26,7 @@ import net.kyori.adventure.text.format.NamedTextColor;
public class CoreVelocityPlugin {
@Inject
public CoreVelocityPlugin(ProxyServer server) {
ScrowAPISurface.initScrowAPI(server, true);
ScrowAPISurface.initScrowAPI(server);
var cmds = ScrowAPI.getCommandApi();
{

View file

@ -4,42 +4,53 @@ import com.velocitypowered.api.proxy.ProxyServer;
import de.kentoj.kencommandapi.CommandAPI;
import de.kentoj.scrow.velocity.ScrowAPI;
import de.kentoj.scrowlib.instancemanager.InstanceManagerImpl;
import de.kentoj.scrowlib.messaging.MessageBroker;
import de.kentoj.scrowlib.messaging.InMemoyMessageBroker;
import de.kentoj.scrowlib.messaging.NatsMessageBroker;
import de.kentoj.scrowlib.player.NetworkPlayerImpl;
import de.kentoj.scrowlib.utils.EnvUtils;
import io.nats.client.Nats;
import io.nats.client.Options;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jdbi.v3.core.Jdbi;
import java.io.IOException;
import java.util.Properties;
@Slf4j
@NoArgsConstructor(access = AccessLevel.NONE)
public class ScrowAPISurface {
public static void initScrowAPI(ProxyServer server, boolean enableDatabase) {
try {
String natsHost = EnvUtils.envOrThrow("HOST_NATS");
var options = Options.builder()
.server(natsHost)
.pedantic()
.build();
ScrowAPI.setMessageBroker(new MessageBroker(Nats.connect(options)));
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
public static void initScrowAPI(ProxyServer server) {
var natsHost = System.getenv("HOST_NATS");
if (natsHost != null) {
try {
var options = Options.builder()
.server(natsHost)
.pedantic()
.build();
ScrowAPI.setMessageBroker(new NatsMessageBroker(Nats.connect(options)));
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
} else {
log.error("HOST_NATS not set -> Using in-memory dummy message broker");
ScrowAPI.setMessageBroker(new InMemoyMessageBroker());
}
if (enableDatabase) {
var hostPostgres = System.getenv().get("HOST_POSTGRES");
if (hostPostgres != null) {
try {
Class.forName("org.postgresql.Driver", true, ScrowAPISurface.class.getClassLoader());
var props = new Properties();
props.setProperty("user", "postgres");
ScrowAPI.setJdbi(Jdbi.create(hostPostgres));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
var props = new Properties();
props.setProperty("user", "postgres");
ScrowAPI.setJdbi(Jdbi.create(EnvUtils.envOrThrow("HOST_POSTGRES"), props));
} else {
log.error("HOST_POSTGRES not set -> Using in-memory database");
}
ScrowAPI.setInstanceManager(new InstanceManagerImpl(ScrowAPI.getMessageBroker()));

View file

@ -1,7 +1,5 @@
package de.kentoj.scrow.corevelocity.network;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import com.velocitypowered.api.proxy.ProxyServer;
import de.kentoj.scrow.velocity.ScrowAPI;
import de.kentoj.scrowlib.messaging.MessageBroker;
@ -10,14 +8,16 @@ import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@Slf4j
@RequiredArgsConstructor
public class SendPlayerWatchdog {
private final ExecutorService EXECUTOR = Executors.newVirtualThreadPerTaskExecutor();
private final MessageBroker messageBroker = ScrowAPI.getMessageBroker();
private final ProxyServer server;
@ -28,17 +28,14 @@ public class SendPlayerWatchdog {
));
}
private CompletionStage<Result<Document, String>> sendPlayer(UUID playerId, String handle) {
return CompletableFuture.supplyAsync(() -> {
private Future<Document> sendPlayer(UUID playerId, String handle) {
return EXECUTOR.submit(() -> {
var player = server.getPlayer(playerId).orElseThrow();
var targetServer = server.getServer(handle).orElseThrow();
try {
var res = player.createConnectionRequest(targetServer).connect().get();
return res.isSuccessful() ? Results.success(new Document()) : Results.failure(res.getStatus().name());
} catch (InterruptedException | ExecutionException e) {
log.error("failed to send player to {}", handle, e);
return Results.failure(e.getMessage());
}
var res = player.createConnectionRequest(targetServer).connect().get();
if (!res.isSuccessful())
throw new RuntimeException(res.getStatus().name());
return new Document();
});
}
}