Size: a a a

NodeUA - JavaScript and Node.js in Ukraine

2021 January 29

R

Roman in NodeUA - JavaScript and Node.js in Ukraine
Dmytro Drachov
Правильно ли я понял что проблема такова
1. октрытая страница isOnline=true
2. перезагружаем страницу
3. isOnline=false
4. страница перезагрузилась
5. isOnline=true
6. запрос graphql на сервер отдает isOnline=false?
Да
источник

DD

Dmytro Drachov in NodeUA - JavaScript and Node.js in Ukraine
Roman
Да
ок когда делаеться запрос graph ql?
Как только страница загрузилась или как только ws в получили ping?
источник

R

Roman in NodeUA - JavaScript and Node.js in Ukraine
Dmytro Drachov
ок когда делаеться запрос graph ql?
Как только страница загрузилась или как только ws в получили ping?
После того как отправится по вебсокету подписка, а она отправляется после апдейта статуса юзера

После перезагрузки
источник

KR

Kostyantin Randomnam... in NodeUA - JavaScript and Node.js in Ukraine
Roman
async function pingUserConnection(container, user, ws) {
   const { id: sessId } = await container.resolve('wsSessionParser').parse(ws);
   const db = container.resolve('db');
   let lastPingTime = new Date();
   let lastPongTime = new Date();

   updateUserStatus(user.id, sessId, true, false, container);

   const stopPing = () => {
       clearInterval(intervalId);
       updateUserStatus(user.id, sessId, false, false, container);
   }

   const intervalId = setInterval(() => {
       const shouldMarkOffline = differenceInMinutes(lastPongTime, lastPingTime) > 2;

       if (shouldMarkOffline) {
           stopPing();
           ws.close();
           return
       }

       if (ws.readyState === 1) {
           ws.ping();
           lastPingTime = new Date();
       } else {
           stopPing();
       }
   }, ONE_MINUTE_IN_MILLIS * 2);

   ws.on('pong', async () => {
       lastPongTime = new Date();
       const actualUser = await db.models.user.findByPk(user.id)
       updateUserStatus(user.id, sessId, actualUser.isOnline, actualUser.isSleep, container);
   });

   ws.on('close', () => {
       stopPing();
       ws.close();
   });
}
перевір коли функція стоп пінг викликаєтся, якщо це єдиний спосіб поставити флаг волс
источник

R

Roman in NodeUA - JavaScript and Node.js in Ukraine
Kostyantin Randomname
перевір коли функція стоп пінг викликаєтся, якщо це єдиний спосіб поставити флаг волс
Нет, стоп пинг это лишнее. Это я уже убрал
источник

KR

Kostyantin Randomnam... in NodeUA - JavaScript and Node.js in Ukraine
я щось не бачу щоб ти ласт пінг апдейтив
источник

A

Alexander in NodeUA - JavaScript and Node.js in Ukraine
Dmytro Drachov
Я так понял горький опыт?
Лично я никогда в жизни его в проект не ставил, как и монгусь, но приходилось за другими разгребать.
Если брать только ноду, то в ней я пользовал только одну - objection и то редко.
источник

R

Roman in NodeUA - JavaScript and Node.js in Ukraine
правельно мьютекс встроил?
источник

R

Roman in NodeUA - JavaScript and Node.js in Ukraine
Dmytro Drachov
Правильно ли я понял что проблема такова
1. октрытая страница isOnline=true
2. перезагружаем страницу
3. isOnline=false
4. страница перезагрузилась
5. isOnline=true
6. запрос graphql на сервер отдает isOnline=false?
Добавил мьютекс, но не помогло
async function processConnection(container, user, ws) {
   const mutex = container.resolve('mutex')
   const { id: sessId } = await container.resolve('wsSessionParser').parse(ws);

   await mutex.lock();
   await updateUserStatus(user.id, sessId, true, container)
   mutex.release();

   ws.on('close', async () => {
       await mutex.lock();
       await updateUserStatus(user.id, sessId, false, container)
       ws.close()
       mutex.release();
   });
}
источник

R

Roman in NodeUA - JavaScript and Node.js in Ukraine
Или проблема во фронте?
источник

DD

Dmytro Drachov in NodeUA - JavaScript and Node.js in Ukraine
Roman
После того как отправится по вебсокету подписка, а она отправляется после апдейта статуса юзера

После перезагрузки
т.е с фронта ты делаешь новый вебсокет, ждешь понг который по сути будет через 2минуты(ONE_MINUTE_IN_MILLIS * 2), потом отправляешь якусь подписку, потом дергаешь graphql в котором тебе говорится что юзер офлайн?
источник

R

Roman in NodeUA - JavaScript and Node.js in Ukraine
Dmytro Drachov
т.е с фронта ты делаешь новый вебсокет, ждешь понг который по сути будет через 2минуты(ONE_MINUTE_IN_MILLIS * 2), потом отправляешь якусь подписку, потом дергаешь graphql в котором тебе говорится что юзер офлайн?
Пинг я убрал. Остальное да
источник

DD

Dmytro Drachov in NodeUA - JavaScript and Node.js in Ukraine
Roman
Добавил мьютекс, но не помогло
async function processConnection(container, user, ws) {
   const mutex = container.resolve('mutex')
   const { id: sessId } = await container.resolve('wsSessionParser').parse(ws);

   await mutex.lock();
   await updateUserStatus(user.id, sessId, true, container)
   mutex.release();

   ws.on('close', async () => {
       await mutex.lock();
       await updateUserStatus(user.id, sessId, false, container)
       ws.close()
       mutex.release();
   });
}
C этим кодом та же проблема? одни из 5 фелится ?
источник

R

Roman in NodeUA - JavaScript and Node.js in Ukraine
Уже меньше то все таже проблема
источник

DD

Dmytro Drachov in NodeUA - JavaScript and Node.js in Ukraine
а где ты отправляешь эту подписку на фронт?
источник

R

Roman in NodeUA - JavaScript and Node.js in Ukraine
И еще странно что если сайт открыт на весь экран то постоянно приходит false. А если я его открою на пол экрана то тру приходит. Это очень странно

Подписку  через pubsub
источник

DD

Dmytro Drachov in NodeUA - JavaScript and Node.js in Ukraine
Roman
И еще странно что если сайт открыт на весь экран то постоянно приходит false. А если я его открою на пол экрана то тру приходит. Это очень странно

Подписку  через pubsub
ничего старного, у тебя ж пол экрана, пол сайта, вот и пол кода работает=)
источник

DD

Dmytro Drachov in NodeUA - JavaScript and Node.js in Ukraine
что происходит раньше? подписка приходит на фронт или
await updateUserStatus(user.id, sessId, true, container)
источник

R

Roman in NodeUA - JavaScript and Node.js in Ukraine
Dmytro Drachov
что происходит раньше? подписка приходит на фронт или
await updateUserStatus(user.id, sessId, true, container)
Подписка позже, она отрабатывает после апдейта

updateUser => notifyAboutChangedStatus
а тут graphql запрос на currentUser
источник

DD

Dmytro Drachov in NodeUA - JavaScript and Node.js in Ukraine
Ты ж понимаешь что когда через graph ql api берешь то оно либо еще не закомитело изменение, т.е. висит update_lock и ты берешь старые данные, либо код еще даже не пытался проапдейтить базу, либо возможно(тут я точно не знаю) читаешь из реплики постгресса там где еще апдейт не дошел, либо после апдейта в true у тебя где-то каким-то образом идет апдейт в false.

К сожалению только с этим куском кода я могу только гадать. Тут надо брать запускать фронт и бек и смотреть лог, дебаг тут не особо поможешь бо баг плавающий и если ты будешь останавливаться на дебагером то врядли зарепродьюсишь
источник