Skip to content

Commit

Permalink
Generate abstract server class for server and node
Browse files Browse the repository at this point in the history
  • Loading branch information
HttpMarco committed Nov 26, 2024
1 parent 2ecfffd commit 78c8ee1
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package dev.httpmarco.netline.channel;

import dev.httpmarco.netline.NetChannel;
import dev.httpmarco.netline.NetComp;
import dev.httpmarco.netline.packet.Packet;
import dev.httpmarco.netline.request.Request;
import dev.httpmarco.netline.server.NetServer;
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/dev/httpmarco/netline/node/NetNodeConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dev.httpmarco.netline.node;

import dev.httpmarco.netline.config.CompConfig;

public final class NetNodeConfig extends CompConfig {

public NetNodeConfig() {
super("0.0.0.0", 9091, true, 5);
}
}
19 changes: 19 additions & 0 deletions src/main/java/dev/httpmarco/netline/node/NetNodeState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dev.httpmarco.netline.node;

public enum NetNodeState {

// if node is present, but not started booting
INITIALIZING,
// if node is booting and failed to bind to cluster
FAILED,
// if node is booting and binding to cluster (ip pool)
BIND_CLUSTER,
// if node is booting and syncing with cluster
SYNC_CLUSTER,
// if node is booting and ready to accept connections
READY,
// if node is shutting down
CLOSED


}
69 changes: 69 additions & 0 deletions src/main/java/dev/httpmarco/netline/server/AbstractNetServer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package dev.httpmarco.netline.server;

import dev.httpmarco.netline.NetChannel;
import dev.httpmarco.netline.NetCompHandler;
import dev.httpmarco.netline.channel.NetChannelInitializer;
import dev.httpmarco.netline.config.CompConfig;
import dev.httpmarco.netline.impl.AbstractNetCompImpl;
import dev.httpmarco.netline.utils.NetworkUtils;
import io.netty5.bootstrap.ServerBootstrap;
import io.netty5.channel.ChannelOption;
import io.netty5.channel.EventLoopGroup;
import io.netty5.channel.epoll.Epoll;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.CompletableFuture;

public abstract class AbstractNetServer<C extends CompConfig> extends AbstractNetCompImpl<C> {

private final EventLoopGroup workerGroup = NetworkUtils.createEventLoopGroup(0);

public AbstractNetServer(C config) {
super(1, config);
}


@Override
public CompletableFuture<Void> boot() {
var future = new CompletableFuture<Void>();

var bootstrap = new ServerBootstrap()
.group(bossGroup(), workerGroup)
.childHandler(new NetChannelInitializer(handler()))
.channelFactory(NetworkUtils.generateChannelFactory())
.childOption(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.IP_TOS, 24)
.childOption(ChannelOption.SO_KEEPALIVE, true);

if (config().tryTcpFastOpen() && Epoll.isTcpFastOpenServerSideAvailable()) {
bootstrap.childOption(ChannelOption.TCP_FASTOPEN_CONNECT, true);
}

bootstrap.bind(config().hostname(), config().port()).addListener(it -> {
if(it.isSuccess()) {
this.onBindSuccess();
future.complete(null);
return;
}
this.onBindFail(it.cause());
future.completeExceptionally(it.cause());
});

return future;
}

@Override
public @NotNull CompletableFuture<Void> close() {
var future = new CompletableFuture<Void>();
this.bossGroup().shutdownGracefully().addListener(it -> onClose().whenComplete((unused, throwable) -> future.complete(null)));
return future;
}

public abstract CompletableFuture<Void> onClose();

public abstract void onBindFail(Throwable throwable);

public abstract void onBindSuccess();

public abstract NetCompHandler handler();
}
85 changes: 27 additions & 58 deletions src/main/java/dev/httpmarco/netline/server/NetServer.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
package dev.httpmarco.netline.server;

import dev.httpmarco.netline.NetChannel;
import dev.httpmarco.netline.channel.NetChannelInitializer;
import dev.httpmarco.netline.NetCompHandler;
import dev.httpmarco.netline.channel.NetClientChannel;
import dev.httpmarco.netline.impl.AbstractNetCompImpl;
import dev.httpmarco.netline.packet.Packet;
import dev.httpmarco.netline.packet.common.ChannelIdentifyPacket;
import dev.httpmarco.netline.request.ResponderRegisterPacket;
import dev.httpmarco.netline.security.SecurityHandler;
import dev.httpmarco.netline.tracking.server.ClientConnectedTracking;
import dev.httpmarco.netline.utils.NetworkUtils;
import io.netty5.bootstrap.ServerBootstrap;
import io.netty5.channel.Channel;
import io.netty5.channel.ChannelOption;
import io.netty5.channel.EventLoopGroup;
import io.netty5.channel.epoll.Epoll;
import lombok.Getter;
import lombok.experimental.Accessors;
import org.jetbrains.annotations.Contract;
Expand All @@ -26,51 +20,18 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Predicate;

@Getter
@Accessors(fluent = true)
public final class NetServer extends AbstractNetCompImpl<NetServerConfig> {

private final EventLoopGroup workerGroup = NetworkUtils.createEventLoopGroup(0);
@Getter
@NotNull
private final List<NetClientChannel> clients = new CopyOnWriteArrayList<>();
@Getter
public final class NetServer extends AbstractNetServer<NetServerConfig> {
@NotNull
private NetServerState state = NetServerState.INITIALIZE;
@Getter
@NotNull
private final List<NetClientChannel> clients = new CopyOnWriteArrayList<>();
@Nullable
private SecurityHandler securityHandler;

public NetServer() {
super(1, new NetServerConfig());
}

@Override
public CompletableFuture<Void> boot() {
this.state = NetServerState.BOOTING;
var future = new CompletableFuture<Void>();

var bootstrap = new ServerBootstrap()
.group(bossGroup(), workerGroup)
.childHandler(new NetChannelInitializer(new NetServerHandler(this)))
.channelFactory(NetworkUtils.generateChannelFactory())
.childOption(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.IP_TOS, 24)
.childOption(ChannelOption.SO_KEEPALIVE, true);


if (config().tryTcpFastOpen() && Epoll.isTcpFastOpenServerSideAvailable()) {
bootstrap.childOption(ChannelOption.TCP_FASTOPEN_CONNECT, true);
}

bootstrap.bind(config().hostname(), config().port()).addListener(it -> {
if(it.isSuccess()) {
this.state = NetServerState.BOOTED;
future.complete(null);
return;
}
this.state = NetServerState.FAILED;
future.completeExceptionally(it.cause());
});
super(new NetServerConfig());

responderOf("channel_identification", (channel, properties) -> {
this.clients.add((NetClientChannel) channel);
Expand All @@ -79,19 +40,6 @@ public CompletableFuture<Void> boot() {
});

track(ResponderRegisterPacket.class, (channel, packet) -> responders().put(packet.id(), (channel1, stringStringMap) -> channel.request(packet.id(), Packet.class).sync()));
return future;
}

@Override
public @NotNull CompletableFuture<Void> close() {
var future = new CompletableFuture<Void>();

this.bossGroup().shutdownGracefully().addListener(it -> CompletableFuture.allOf(this.clients.stream().map(NetChannel::close).toArray(CompletableFuture[]::new)).whenComplete((unused, throwable) -> {
this.clients.clear();
this.state = NetServerState.CLOSED;
future.complete(null);
}));
return future;
}

@Override
Expand All @@ -112,6 +60,27 @@ public void send(String id, Packet packet) {
public void send(Predicate<NetClientChannel> predicate, Packet packet) {
this.clients.stream().filter(predicate).forEach(channel -> channel.send(packet));
}
@Override
public CompletableFuture<Void> onClose() {
var future = CompletableFuture.allOf(this.clients.stream().map(NetClientChannel::close).toArray(CompletableFuture[]::new));
this.state = NetServerState.CLOSED;
return future;
}

@Override
public void onBindFail(Throwable throwable) {
this.state = NetServerState.FAILED;
}

@Override
public void onBindSuccess() {
this.state = NetServerState.BOOTED;
}

@Override
public NetCompHandler handler() {
return new NetServerHandler(this);
}

public void withSecurityPolicy(SecurityHandler securityHandler) {
this.securityHandler = securityHandler;
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/dev/httpmarco/netline/NetLineTestSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

@Suite
@SelectClasses({
CompBindingTest.class, PacketTransmitTest.class, SecurityListTest.class, PacketRequestTest.class, BroadcastTest.class
CompBindingTest.class, PacketTransmitTest.class, SecurityListTest.class, PacketRequestTest.class, BroadcastTest.class, NodeTest.class
})
@SuiteDisplayName("NetLine Test Suite")
public class NetLineTestSuite {
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/dev/httpmarco/netline/tests/NodeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package dev.httpmarco.netline.tests;

import dev.httpmarco.netline.node.NetNodeState;
import org.junit.jupiter.api.*;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@DisplayName("5 - Node cluster test")
public class NodeTest {

/*
private static NetNode node;
@BeforeAll
public static void beforeHandling() {
node = new NetNode();
}
@Test
@Order(1)
@DisplayName("5.1 Start first node")
public void testState() {
assert node.state() == NetNodeState.INITIALIZING;
node.bootSync();
assert node.state() == NetNodeState.READY;
}
*/
}

0 comments on commit 78c8ee1

Please sign in to comment.