Add UserRegistry to store all existing users and UserCleanupJob to periodicly remove expired user #189

Merged
lars.winzer merged 12 commits from feat/user-serverside into main 2026-03-15 20:00:59 +01:00
Showing only changes of commit 8fae4789ad - Show all commits
@@ -1,56 +1,27 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.user; package ch.unibas.dmi.dbis.cs108.casono.server.domain.user;
import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public class UserRegistry { public class UserRegistry {
private final ConcurrentHashMap<UserId, User> byId = new ConcurrentHashMap<>(); private final ConcurrentHashMap<UserId, User> byId = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, User> byName = new ConcurrentHashMap<>();
private final ConcurrentHashMap<SessionId, User> bySessionId = new ConcurrentHashMap<>();
public synchronized Optional<User> registerIfAvailable(String name, SessionId sessionId) { public synchronized Optional<User> registerIfAvailable(String name, SessionId sessionId) {
Iterator<User> users = byId.elements().asIterator(); if (byName.containsKey(name)) {
while(users.hasNext()) { return Optional.empty();
User user = users.next();
if (user.getName() == name) {
return Optional.empty();
}
} }
User user = new User(new UserId(), name, sessionId); User user = new User(new UserId(), name, sessionId);
byId.put(user.getId(), user); byId.put(user.getId(), user);
byName.put(user.getName(), user);
bySessionId.put(sessionId, user);
return Optional.of(user); return Optional.of(user);
} }
public Optional<User> findBySessionId(SessionId sessionId) {
Iterator<User> users = byId.elements().asIterator();
while(users.hasNext()) {
User user = users.next();
Optional<SessionId> currentSessionId = user.getSessionId();
if (currentSessionId.isEmpty()) {
continue;
}
if (currentSessionId.get() == sessionId) {
return Optional.of(user);
}
}
return Optional.empty();
}
// TODO: Add to EventRegistry with DisconnectEvent
public synchronized void onDisconnect(SessionId sessionId) {
Optional<User> user = findBySessionId(sessionId);
if (user.isPresent()) {
user.get().markDisconnected();
}
}
public synchronized boolean removeIfStillDisconnected(UserId userId) { public synchronized boolean removeIfStillDisconnected(UserId userId) {
User user = byId.get(userId); User user = byId.get(userId);
if (user == null) { if (user == null) {
@@ -62,17 +33,35 @@ public class UserRegistry {
} }
byId.remove(user.getId()); byId.remove(user.getId());
byName.remove(user.getName());
return true; return true;
} }
// TODO: Add to EventRegistry with DisconnectEvent
public synchronized void onDisconnect(SessionId sessionId) {
User user = bySessionId.remove(sessionId);
if (user == null) {
return;
}
user.markDisconnected();
}
public synchronized Optional<User> reassignSession(UserId userId, SessionId sessionId) { public synchronized Optional<User> reassignSession(UserId userId, SessionId sessionId) {
User user = byId.get(userId); User user = byId.get(userId);
if (user == null) return Optional.empty(); if (user == null) {
return Optional.empty();
}
user.reassignSession(sessionId); user.reassignSession(sessionId);
bySessionId.put(sessionId, user);
return Optional.of(user); return Optional.of(user);
} }
public Optional<User> findBySessionId(SessionId sessionId) {
return Optional.ofNullable(bySessionId.get(sessionId));
}
public Collection<User> getAllUsers() { public Collection<User> getAllUsers() {
return byId.values(); return byId.values();
} }