Не знаю как еще обозвать тему, я не знаю что делать и почему так получается, может я просто чего-то не понимаю (совсем недавно начал пробовать nodejs), рассмотрим проблему на простой регистрации пользователя, кусок кода:
const register = (req, res, next) => {
const { name, email, password, passwordConfirmation } = req.body
async.waterfall([
cb => {
bcrypt.genSalt(10, (err, salt) => {
if (err) return cb(err);
bcrypt.hash(password, salt, cb);
})
}
], (err, results) => {
if (err) {
logger.error(err);
return ...
}
User.findOne({
where : {
$or : [
{name},
{email}
]
}
}).asCallback((err, model) => {
if (err) {
logger.error(err);
return ...
}
if (model && model.name == name) return ...name already exists
if (model && model.email == email) return ...email already exists
// create user
User.create({
name,
email,
password : results,
}, (err, model) => {
if (err) {
logger.error(err);
return ...
}
// done
return ...
})
})
})
}
Проблема в следующем, при 2 одновременных запросах с одинаковыми данными, первый успешно будет создан, второй вылетит ошибка дублирования индексов, т.к несмотря на проверку существования name/email запрос проверки выполняется до создания 1 пользователя. Я могу решить эту проблему обернув эту операцию в некую очередь и регистрировать всех пользователей строго по очереди, но будет ли это правильным?
Выявить это получилось небольшими стресс-тестами, ради интереса я зашел на prod, в консоли прописал 2 запроса ткнул enter, увидел в логах тоже самое... И я бы пожалуй забил на это, не будь у меня мест в коде, где проверки существования чего-либо немного более важны, чем тут, но это самый простой пример.