Mongoose findOneAndUpdate () блокирует запросы socket.io? - PullRequest
0 голосов
/ 03 октября 2018

Я не уверен, есть ли что-то, чего я не понимаю, или есть какая-то ошибка, но я просто не могу понять это.По сути, время от времени я отправляю запрос со своего сервера в API, чтобы получить некоторую информацию, а затем сохраняю ее в своей базе данных, но всякий раз, когда данные сохраняются, запросы socket.io блокируются и только тогда, когда все данныебыл обновлен, когда другие запросы поступают в кучу.Я знаю, что они блокируются, потому что я пытался отправлять сообщение чата каждые 100 мс, пока обновлялись данные, и все сообщения приходили ТОЛЬКО, когда последний фрагмент информации из API был сохранен, а ни один не был получен во время его обработки.сохранены.Как сделать так, чтобы он не блокировал другие запросы?

Вот пример вывода на консоль, когда я тестировал его:

...
New chat message received
New chat message received
New chat message received
New chat message received
UPDATING 1455 ITEMS
UPDATED ALL PRICES, TOOK 3592
New chat message received
New chat message received
New chat message received
New chat message received
...

код:

request('url')), (err, response, body) => {
        let items = JSON.parse(body);
        let startTime = new Date().getTime();
        console.log(`UPDATING ${items.prices.length} ITEMS`);

        for (let i = 0; i < items.prices.length; i++) {
            const item = items.prices[i];

            Prices.findOneAndUpdate({item: item.name}, {$set: {price: item.price, last_update: Date.now()}}, (err, res) => {
                if(!res){
                    newPrice = new Prices({
                        item: item.name,
                        price: item.price
                    });

                    newPrice.save((err, saved) => {
                        if (err) {
                            console.log(err);
                        }
                    })
                }

                if(i == items.prices.length - 1){
                    console.log(`UPDATED ALL PRICES, TOOK ${new Date().getTime() - startTime}`);                    
                }
            });
        }
});

Не уверен, поможет ли это с чем-нибудь, но вот код, который обрабатывает получение сообщений:

socket.on('sendMessage', (data) => {
    User.findOne({id: socket.request.user.id}, (err, user) => {
        if (err) throw err;

        //Check if the user is muted and if not, proceed
        if(user.mutedUntil < Date.now()){
            User.findOneAndUpdate({id: socket.request.user.id}, {$set: {lastMessageDate: Date.now()}}, (err, dbUser) => {
                if (err) throw err;

                let parsed = ParseMessage(data.message);                     

                if(parsed.command === 'none'){
                    SendMessage(dbUser, socket, data);
                }else{
                    commandData = {parsed: parsed, socket: socket}
                    ExecuteChatCommand(commandData);
                }
            });
        }else{
            socket.emit('serverMessage', {
                type: 'error',
                title: 'You\'re muted',
                message: 'You are muted and can\'t chat until ' + user.mutedUntil
            });
            console.log('Muted user tried chatting');
        }
    });       
});

1 Ответ

0 голосов
/ 03 октября 2018

Ваш цикл for выполняет блокировку, поскольку это синхронная операция.

Вам следует рассмотреть возможность использования Promises .Вместо цикла for используйте Promise.map or Promise.all в BlueBird или Promise.all в ES6 для достижения того же, но асинхронным способом.

Для ваших запросов вы можете использовать mongoose .exec () , чтобы преобразовать их в полноценные обещания.

Примечание : вы пытаетесьнайти и обновить 1455 раз в этом цикле for ... Может быть, загляните в Promise.mapSeries в Bluebird, чтобы не все обещания одновременно отправлялись в Монго, но в последовательном порядке

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...