Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 28.04.2018, 15:48
Аспирант
Отправить личное сообщение для stweet Посмотреть профиль Найти все сообщения от stweet
 
Регистрация: 21.12.2011
Сообщений: 41

Вот и я так думал, пока не попробовал это сделать используя базу данных. На примере обычного(локального) счетчика у меня тоже все чистенько.
Ответить с цитированием
  #12 (permalink)  
Старый 28.04.2018, 15:51
Аватар для EmperioAf
Профессор
Отправить личное сообщение для EmperioAf Посмотреть профиль Найти все сообщения от EmperioAf
 
Регистрация: 15.01.2015
Сообщений: 622

Значит у вас проблема в логике на БД

async function registerUser(data) { // Promise<number>
    // ...
    // register_user - хранимка, возвращает integer id-а пользователя, вся логика работы с данными в ней описана
    const id = (await db.query('SELECT register_user as id FROM register_user(%)', [data])).id;
    // ...
    return id;
}

/* 
    если в БД все правильно сделано и id пользователя это primary key, 
    и например выдается какой-то последовательностью(например user_id_sequence), 
    то вы никогда не получите два одинаковых id-а вызвав функцию registerUser
*/
Ответить с цитированием
  #13 (permalink)  
Старый 28.04.2018, 15:52
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,492

Сообщение от stweet Посмотреть сообщение
Если одновременно "два" юзера жмякнут на "поднять" оба получают "4". А в базе стоит "5" - !неудачный пример!
По логике - нет. Если изначально там 3, то один юзер получит 4 - другой 5. Какой - что - зависит от сетевых задержек. Понятия "одновременно" - не существует.
Вы можете искусственно накапливать обращения, приходящие по очереди с интервалом меньше n, и, как только дольше чем n не было обращений, красиво отправлять в базу одним куском и красиво же отправлять обратно всем, но зачем?

...upd
Сообщение от EmperioAf Посмотреть сообщение
Значит у вас проблема в логике на БД
Кстати да, такую мысль я даж не допускал.) В таком случае возможно что угодно.

...upd
Если уж так хочется красоты - можно сделать переменную someCount и при получении любого соответствующего ответа от базы проверять если та меньше возвращённого значения - устанавливать оное. И при ответе пользователю использовать уже её. Всё равно это не ничего не гарантирует, но будет немного "красивее".
__________________
29375, 35

Последний раз редактировалось Aetae, 28.04.2018 в 16:02.
Ответить с цитированием
  #14 (permalink)  
Старый 28.04.2018, 15:59
Аватар для Белый шум
Профессор
Отправить личное сообщение для Белый шум Посмотреть профиль Найти все сообщения от Белый шум
 
Регистрация: 19.01.2012
Сообщений: 498

Сообщение от stweet
Что бы не получилось так, пока один юзер пытается поднять счетчик второй пытается его понизить и т.д.
Если вам нужен контроль счётчика пользователем, то логичнее периодически делать запросы к серверу и обновлять значение на странице. Иначе, разные пользователи всё-равно будут видеть разные цифры - по порядку вы им отдадите результат или нет.
Ответить с цитированием
  #15 (permalink)  
Старый 28.04.2018, 16:00
Аватар для EmperioAf
Профессор
Отправить личное сообщение для EmperioAf Посмотреть профиль Найти все сообщения от EmperioAf
 
Регистрация: 15.01.2015
Сообщений: 622

В общем вопрос такой:
как выглядит ваша функция Model.incCounterByType?
Если это вызов к postgresql типа:
UPDATE counters SET counter = counter + 1 WHERE type = % RETURNING counter;
то все должно нормально работать
Ответить с цитированием
  #16 (permalink)  
Старый 28.04.2018, 16:08
Аспирант
Отправить личное сообщение для stweet Посмотреть профиль Найти все сообщения от stweet
 
Регистрация: 21.12.2011
Сообщений: 41

Давайте на примере игры рассмотрим данную задачу. Допустим есть игра "однорукий бандит" (рулетка) и у нее есть общий баланс. Так вот, если 50 пользователей запустят эту игру (у каждого свой инстанц но общий баланс игры), выполняя какие то действия будут изменять состояние общего баланса игры. Меня пугает то, что в цикле разные ответы.
Т.е. пользователь "i" делает запрос на изменение общего баланса игры и получает "левый" ответ в тот момент когда должен был получить свой. Посмотрите внимательно на мною приведенный код в старте топика.
Ответить с цитированием
  #17 (permalink)  
Старый 28.04.2018, 16:10
Аспирант
Отправить личное сообщение для stweet Посмотреть профиль Найти все сообщения от stweet
 
Регистрация: 21.12.2011
Сообщений: 41

Да, я рассматривал данное решение, но, если в момент хранения данных в памяти а не в базе рухнет сервер то он утащит за собой и память. А подняв будет масса вопросов у пользователей!
Ответить с цитированием
  #18 (permalink)  
Старый 28.04.2018, 16:12
Аспирант
Отправить личное сообщение для stweet Посмотреть профиль Найти все сообщения от stweet
 
Регистрация: 21.12.2011
Сообщений: 41

Как раз так и выглядит. Но в старте топика я вывел вам данные консоли, и они не по порядку, это меня и пугает. В базе все вроде бы пучком но ответы на запросы разные. Т.е. запрашиваемый может получить ответ предыдущего и на оборот.
Ответить с цитированием
  #19 (permalink)  
Старый 28.04.2018, 16:16
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,492

stweet, каждый получает свой ответ.
Проблема исключительно в порядке. Но порядок в случае с пользователями не важен. Проблема решена.
__________________
29375, 35
Ответить с цитированием
  #20 (permalink)  
Старый 28.04.2018, 16:19
Аватар для EmperioAf
Профессор
Отправить личное сообщение для EmperioAf Посмотреть профиль Найти все сообщения от EmperioAf
 
Регистрация: 15.01.2015
Сообщений: 622

Между этим кодом никакой разницы нет. Он делает одно и то же.
let last = Promise.resolve({})
for(let i  = 0; i < 1000; i ++) {
    last  = last .then(() => Model.incCounterByType(«one»))
        .then(res => console.log(`${i}, ${type}, ${res.counter}`))
        .catch(console.error);
}

for(let i  = 0; i < 1000; i ++) {
    try {
        const res  = await Model.incCounterByType(«one»))
        console.log(`${i}, ${type}, ${res.counter}`)
    } catch(err) {
        console.error(err);
    }
}
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Запись видео с экрана prog77 Библиотеки/Тулкиты/Фреймворки 5 10.02.2020 18:31
getUserMedia() как отследить последующие изменения разрешений на запись? Amateur Элементы интерфейса 0 20.10.2015 22:30
Store - просто удалить запись Infarch ExtJS 1 12.08.2014 17:46
VK - разместить запись на стену lol4eg Общие вопросы Javascript 8 23.02.2013 14:52
Как сделать чтобы пользователь только мог 2 раза прослушать запись? KOTDG AJAX и COMET 0 11.02.2012 22:37