Node-persist в тяжелом приложении Node.js, не возвращающем значения - PullRequest
0 голосов
/ 01 октября 2018

У меня есть приложение с тяжелым узлом, и я использую node-persist для сохранения данных в локальную базу данных.

На определенном этапе у меня есть это:

const localdb = require('node-persist')
const storage = localdb.create({ttl: true})
await storage.init()

function game(socket, log, opts) {

   // [...]

    async function scoreHandler(data) {
        if (data.scoreUp) {
            await storage.setItem(data.sid,data.uid)
        } else if (data.scoreDown) {
            try {
                let uid = await storage.getItem(data.sid);

                if (typeof uid == 'undefined') {
                    return;
                }

                console.log(uid);
            } catch (e) {
                return;
            }
        }
    }
}

Этот коднемного глубоко в длинной функции.Все очень просто.Но есть две проблемы:

  1. Чаще, чем uid равен undefined.Я предполагаю, что файл еще не был сохранен, поэтому, когда я пытаюсь получить для негоIItem, он имеет неопределенное значение.
  2. Даже при этом if (uid == 'undefined'), console.log(uid) по-прежнему выдает много undefined,Я не могу понять, почему, так как я "возвращаюсь".

Код на самом деле просто так.Это if, вероятно, вызывается 15-20 раз в секунду.Нет другого фрагмента кода, который может выдавать «undefined» на консоли, или чего-либо, записывающего в базу данных.

Почему это происходит?И что я могу сделать, чтобы правильно с этим справиться?

Edit 1

Точка 2 я разобрался.Я забыл поставить typeof.

Редактировать 2

Я добавил init в соответствии с просьбой.

Если я удаляю try...catch, Я получаю эту ошибку довольно часто:

(node:9608) UnhandledPromiseRejectionWarning: Error: [node-persist][readFile] ... does not look like a valid storage file!
    at fs.readFile (...node-persist/src/local-storage.js:277:66)
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:511:3)

Итак, я предполагаю, что getItem пытается прочитать файл, который setItem еще не закончил писать.

Ответы [ 2 ]

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

Чтобы добавить немного к тому, что говорит @ t.niese, в принципе, нет параллелизма, предоставляемого библиотекой.Одним из решений будет сериализация звонков в библиотеку.Ниже приведен пример кода, который сериализует все обращения к библиотеке.

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

Сказав все это, это должно быть обработано в библиотеке.

закомментируйте и раскомментируйте выбор хранилища для сохранения узла или обертки вокруг сохранения узла.

const localdb = require('node-persist')
const when = require('when');


class QueuedStorage  {

  constructor() {
    this.storage = localdb.create({ ttl: true, logging: false})
  }

  async init() {
    await this.storage.init();
  }


  async getItem(key) {
    this.current = when(this.current,
            () => { return this.storage.getItem(key)},
            () => { return this.storage.getItem(key)});
    return this.current;
  }

  async setItem(key, value)  {
    this.current = when(this.current,
            () => { return this.storage.setItem(key,value)},
            () => { return this.storage.setItem(key,value)});
    return this.current;
  }
};


//const storage  = new QueuedStorage();
const storage = localdb.create({ ttl: true, logging: true })


async function main () {
  await storage.init()

  try {
    const key = 'DSF-AS-558-DDDF';
    const fs = new Array(10000)
      .fill(0)
      .map((e,i) => function() {
        if(i%2) return storage.getItem(key)
        else return storage.setItem(key,i)}());

    Promise.all(fs).then(values => console.log(values));

   } catch (err) {
     console.error(err)
   }
}

main().catch(err => {
  console.error(err)
})
0 голосов
/ 01 октября 2018

Кажется, что node-persist не обрабатывает одновременные операции чтения и записи надежно.

Если getItem вызывается во время выполнения setItem, то эта ошибка будет выдана.

Единственное решение: либо это исправлено библиотекой, либо вы гарантируете, что никогда не наберете getItem, пока setItem.

Мое предложение - обернуть все, что связано с этим хранилищем.в собственный класс.Чтобы потом можно было легко заменить его другой библиотекой.

Я заполнил вопрос:

Одновременный setItem и getItem может привести к неуправляемости does not look like a valid storage file

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