Purge the awful refreshAccount logic
User.prototype.refreshAccount was responsible for multiple race
condition bugs as well as inefficient duplication of DB queries in an
attempt to correct such race conditions.
It has now been replaced by a more reasonable model:
* Global user account information and aliases are fetched in parallel
on socket connection
* Channel rank is fetched when the user tries to join a channel
This commit is contained in:
parent
014eb28e0d
commit
99760b6989
7 changed files with 132 additions and 232 deletions
|
|
@ -30,21 +30,15 @@ AccessControlModule.prototype.onUserPreJoin = function (user, data, cb) {
|
|||
} else {
|
||||
user.socket.emit("needPassword", typeof data.pw !== "undefined");
|
||||
/* Option 1: log in as a moderator */
|
||||
user.waitFlag(Flags.U_LOGGED_IN, function () {
|
||||
user.channel = chan;
|
||||
user.refreshAccount(function (err, account) {
|
||||
/* Already joined the channel by some other condition */
|
||||
if (user.is(Flags.U_IN_CHANNEL)) {
|
||||
return;
|
||||
} else if (user.channel === chan) {
|
||||
user.channel = null;
|
||||
}
|
||||
user.waitFlag(Flags.U_HAS_CHANNEL_RANK, function () {
|
||||
if (user.is(Flags.U_IN_CHANNEL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (account.effectiveRank >= 2) {
|
||||
cb(null, ChannelModule.PASSTHROUGH);
|
||||
user.socket.emit("cancelNeedPassword");
|
||||
}
|
||||
});
|
||||
if (user.account.effectiveRank >= 2) {
|
||||
cb(null, ChannelModule.PASSTHROUGH);
|
||||
user.socket.emit("cancelNeedPassword");
|
||||
}
|
||||
});
|
||||
|
||||
/* Option 2: Enter correct password */
|
||||
|
|
|
|||
|
|
@ -329,41 +329,33 @@ Channel.prototype.joinUser = function (user, data) {
|
|||
}
|
||||
|
||||
user.channel = self;
|
||||
if (self.is(Flags.C_REGISTERED)) {
|
||||
user.refreshAccount(function (err, account) {
|
||||
if (err) {
|
||||
Logger.errlog.log("user.refreshAccount failed at Channel.joinUser");
|
||||
Logger.errlog.log(err.stack);
|
||||
self.refCounter.unref("Channel::user");
|
||||
return;
|
||||
user.waitFlag(Flags.U_LOGGED_IN, () => {
|
||||
db.channels.getRank(self.name, user.getName(), (error, rank) => {
|
||||
if (!error) {
|
||||
user.setChannelRank(rank);
|
||||
user.setFlag(Flags.U_HAS_CHANNEL_RANK);
|
||||
}
|
||||
|
||||
afterAccount();
|
||||
});
|
||||
} else {
|
||||
afterAccount();
|
||||
});
|
||||
|
||||
if (user.socket.disconnected) {
|
||||
self.refCounter.unref("Channel::user");
|
||||
return;
|
||||
} else if (self.dead) {
|
||||
return;
|
||||
}
|
||||
|
||||
function afterAccount() {
|
||||
if (user.socket.disconnected) {
|
||||
self.checkModules("onUserPreJoin", [user, data], function (err, result) {
|
||||
if (result === ChannelModule.PASSTHROUGH) {
|
||||
user.channel = self;
|
||||
self.acceptUser(user);
|
||||
} else {
|
||||
user.channel = null;
|
||||
user.account.channelRank = 0;
|
||||
user.account.effectiveRank = user.account.globalRank;
|
||||
self.refCounter.unref("Channel::user");
|
||||
return;
|
||||
} else if (self.dead) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.checkModules("onUserPreJoin", [user, data], function (err, result) {
|
||||
if (result === ChannelModule.PASSTHROUGH) {
|
||||
user.channel = self;
|
||||
self.acceptUser(user);
|
||||
} else {
|
||||
user.channel = null;
|
||||
user.account.channelRank = 0;
|
||||
user.account.effectiveRank = user.account.globalRank;
|
||||
self.refCounter.unref("Channel::user");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -401,7 +393,6 @@ Channel.prototype.acceptUser = function (user) {
|
|||
if (user.account.globalRank === 0) loginStr += " (guest)";
|
||||
loginStr += " (aliases: " + user.account.aliases.join(",") + ")";
|
||||
self.logger.log(loginStr);
|
||||
|
||||
self.sendUserJoin(self.users, user);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue