Atomically check for existing user with requested nickname and add new user if there is not such an existing user. Fixes #26.

This commit is contained in:
Andy Janata 2012-12-29 12:57:31 -08:00
parent 5a52a48976
commit 20cf5ed3cc
2 changed files with 30 additions and 22 deletions

View File

@ -71,18 +71,24 @@ public class ConnectedUsers {
}
/**
* Add a new user.
*
* @param user
* User to add.
* Checks to see if a user with the specified nickname already exists, and if not add the user,
* as an atomic operation.
* @param user User to add. {@code getNickname()} is used to determine the nickname.
* @return {@code true} if the user was added, {@code false} if another user with the same name
* already existed.
*/
public void newUser(final User user) {
public boolean checkAndAdd(final User user) {
synchronized (users) {
if (this.hasUser(user.getNickname())) {
return false;
} else {
users.put(user.getNickname().toLowerCase(), user);
final HashMap<ReturnableData, Object> data = new HashMap<ReturnableData, Object>();
data.put(LongPollResponse.EVENT, LongPollEvent.NEW_PLAYER.toString());
data.put(LongPollResponse.NICKNAME, user.getNickname());
broadcastToAll(MessageType.PLAYER_EVENT, data);
return true;
}
}
}
@ -188,6 +194,7 @@ public class ConnectedUsers {
*/
public void broadcastToList(final Collection<User> broadcastTo, final MessageType type,
final HashMap<ReturnableData, Object> masterData) {
// TODO I think this synchronized block is pointless.
synchronized (users) {
for (final User u : broadcastTo) {
@SuppressWarnings("unchecked")

View File

@ -86,12 +86,10 @@ public class RegisterHandler extends Handler {
final String nick = request.getParameter(AjaxRequest.NICKNAME).trim();
if (!validName.matcher(nick).matches()) {
return error(ErrorCode.INVALID_NICK);
} else if (users.hasUser(nick)) {
return error(ErrorCode.NICK_IN_USE);
} else {
final User user = new User(nick, request.getRemoteAddr(),
Constants.ADMIN_IP_ADDRESSES.contains(request.getRemoteAddr()));
users.newUser(user);
if (users.checkAndAdd(user)) {
// There is a findbugs warning on this line:
// cah/src/net/socialgamer/cah/handlers/RegisterHandler.java:85 Store of non serializable
// net.socialgamer.cah.data.User into HttpSession in
@ -102,6 +100,9 @@ public class RegisterHandler extends Handler {
session.setAttribute(SessionAttribute.USER, user);
data.put(AjaxResponse.NICKNAME, nick);
} else {
return error(ErrorCode.NICK_IN_USE);
}
}
}
return data;