Moved subscriptions to store

This commit is contained in:
Bas de Jong
2025-12-15 10:01:23 +01:00
parent dccf428bb8
commit a7d1a964c2
4 changed files with 94 additions and 14 deletions

View File

@@ -6,6 +6,7 @@ import org.toop.framework.networking.server.challenges.gamechallenge.GameChallen
import org.toop.framework.networking.server.challenges.gamechallenge.GameChallengeTimer; import org.toop.framework.networking.server.challenges.gamechallenge.GameChallengeTimer;
import org.toop.framework.networking.server.client.NettyClient; import org.toop.framework.networking.server.client.NettyClient;
import org.toop.framework.networking.server.stores.ClientStore; import org.toop.framework.networking.server.stores.ClientStore;
import org.toop.framework.networking.server.stores.SubscriptionStore;
import org.toop.framework.networking.server.stores.TurnBasedGameStore; import org.toop.framework.networking.server.stores.TurnBasedGameStore;
import org.toop.framework.networking.server.stores.TurnBasedGameTypeStore; import org.toop.framework.networking.server.stores.TurnBasedGameTypeStore;
import org.toop.framework.utils.ImmutablePair; import org.toop.framework.utils.ImmutablePair;
@@ -21,7 +22,7 @@ public class Server implements GameServer<TurnBasedGame, NettyClient, Long> {
final private List<GameChallenge> gameChallenges = new CopyOnWriteArrayList<>(); final private List<GameChallenge> gameChallenges = new CopyOnWriteArrayList<>();
final private TurnBasedGameStore gameStore; final private TurnBasedGameStore gameStore;
final private ConcurrentHashMap<String, List<String>> subscriptions; // TODO move to own store / manager final private SubscriptionStore subscriptionStore;
final private Duration challengeDuration; final private Duration challengeDuration;
final private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); final private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
@@ -30,14 +31,15 @@ public class Server implements GameServer<TurnBasedGame, NettyClient, Long> {
Duration challengeDuration, Duration challengeDuration,
TurnBasedGameTypeStore turnBasedGameTypeStore, TurnBasedGameTypeStore turnBasedGameTypeStore,
ClientStore<Long, NettyClient> clientStore, ClientStore<Long, NettyClient> clientStore,
TurnBasedGameStore gameStore TurnBasedGameStore gameStore,
SubscriptionStore subStore
) { ) {
this.gameTypesStore = turnBasedGameTypeStore; this.gameTypesStore = turnBasedGameTypeStore;
this.challengeDuration = challengeDuration; this.challengeDuration = challengeDuration;
this.clientStore = clientStore; this.clientStore = clientStore;
this.gameStore = gameStore; this.gameStore = gameStore;
this.subscriptions = new ConcurrentHashMap<>(); this.subscriptionStore = subStore;
scheduler.schedule(this::serverTask, 0, TimeUnit.MILLISECONDS); scheduler.schedule(this::serverTask, 0, TimeUnit.MILLISECONDS);
} }
@@ -114,16 +116,12 @@ public class Server implements GameServer<TurnBasedGame, NettyClient, Long> {
return; return;
} }
subscriptions.forEach((_, clientNames) -> clientNames.remove(clientName)); subscriptionStore.add(new ImmutablePair<>(gameTypeKey, clientName));
subscriptions.computeIfAbsent(
gameTypeKey,
_ -> new ArrayList<>())
.add(clientName);
} }
@Override @Override
public void unsubscribeClient(String clientName) { public void unsubscribeClient(String clientName) {
subscriptions.forEach((_, clientNames) -> clientNames.remove(clientName)); subscriptionStore.remove(clientName);
} }
@Override @Override
@@ -191,13 +189,12 @@ public class Server implements GameServer<TurnBasedGame, NettyClient, Long> {
} }
private void checkSubscriptions() { private void checkSubscriptions() {
if (subscriptions.isEmpty()) return; if (subscriptionStore.allKeys().isEmpty()) return;
List<String> keys = List.copyOf(subscriptions.keySet());
Random ran = new Random(); Random ran = new Random();
for (String key : keys) { for (String key : subscriptionStore.allKeys()) {
List<String> userNames = subscriptions.get(key); List<String> userNames = (List<String>) subscriptionStore.allValues(key);
if (userNames.size() < 2) continue; if (userNames.size() < 2) continue;
while (userNames.size() > 1) { while (userNames.size() > 1) {

View File

@@ -17,6 +17,7 @@ import org.toop.framework.networking.server.client.NettyClient;
import org.toop.framework.networking.server.connectionHandler.NettyClientSession; import org.toop.framework.networking.server.connectionHandler.NettyClientSession;
import org.toop.framework.networking.server.Server; import org.toop.framework.networking.server.Server;
import org.toop.framework.networking.server.handlers.MessageHandler; import org.toop.framework.networking.server.handlers.MessageHandler;
import org.toop.framework.networking.server.stores.MapSubscriptionStore;
import org.toop.framework.networking.server.stores.NettyClientStore; import org.toop.framework.networking.server.stores.NettyClientStore;
import org.toop.framework.networking.server.stores.TurnBasedGameStore; import org.toop.framework.networking.server.stores.TurnBasedGameStore;
import org.toop.framework.networking.server.stores.TurnBasedGameTypeStore; import org.toop.framework.networking.server.stores.TurnBasedGameTypeStore;
@@ -43,7 +44,8 @@ public class NettyGatewayServer implements GatewayServer {
challengeDuration, challengeDuration,
turnBasedGameTypeStore, turnBasedGameTypeStore,
new NettyClientStore(new ConcurrentHashMap<>()), new NettyClientStore(new ConcurrentHashMap<>()),
new TurnBasedGameStore(new CopyOnWriteArrayList<>()) new TurnBasedGameStore(new CopyOnWriteArrayList<>()),
new MapSubscriptionStore(new ConcurrentHashMap<>())
); );
} }

View File

@@ -0,0 +1,71 @@
package org.toop.framework.networking.server.stores;
import org.toop.framework.utils.ImmutablePair;
import java.util.*;
public class MapSubscriptionStore implements SubscriptionStore {
final private Map<String, List<String>> subscriptions;
public MapSubscriptionStore(Map<String, List<String>> initMap) {
this.subscriptions = initMap;
}
@Override
public void add(ImmutablePair<String, String> adding) {
subscriptions.forEach((_, clientNames) -> clientNames.remove(adding.getRight()));
subscriptions.computeIfAbsent(
adding.getLeft(),
_ -> new ArrayList<>())
.add(adding.getRight());
}
@Override
public void remove(String remover) {
subscriptions.forEach((_, clientNames) -> clientNames.remove(remover));
}
// TODO move server internal code to here
@Override
public ImmutablePair<String, String> get(String getter) {
String foundKey = null;
String foundName = null;
for (var key : subscriptions.keySet()) {
var a = subscriptions.get(key).stream().filter(e -> e.equals(getter)).toList();
if (!a.isEmpty()) {
foundKey = key;
foundName = a.getFirst();
break;
}
}
return new ImmutablePair<>(foundKey, foundName);
}
@Override
public Collection<ImmutablePair<String, String>> all() {
List<ImmutablePair<String, String>> a = new ArrayList<>();
for (var key : subscriptions.keySet()) {
for (var sub : subscriptions.get(key)) {
a.addLast(new ImmutablePair<>(key, sub));
}
}
return a;
}
@Override
public Collection<String> allKeys() {
return subscriptions.keySet();
}
@Override
public Collection<String> allValues(String key) {
return subscriptions.get(key);
}
}

View File

@@ -0,0 +1,10 @@
package org.toop.framework.networking.server.stores;
import org.toop.framework.utils.ImmutablePair;
import java.util.Collection;
public interface SubscriptionStore extends Store<String, ImmutablePair<String, String>> {
Collection<String> allKeys();
Collection<String> allValues(String key);
}