Node-persist on heavy Node.js app not returning values
Node-persist on heavy Node.js app not returning values
我有一个重节点应用程序,我正在使用 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;
}
}
}
}
这段代码在长函数中有点深。一切都很简单。但是有两个问题:
uid
通常是 undefined
。我的猜测是该文件尚未保存,因此当我尝试对其进行 getItem 时,它具有未定义的值。
即使 if (uid == 'undefined')
,console.log(uid)
仍然会抛出许多 undefined
。我不明白为什么,因为我是 "returning".
代码就是这样。这个if
大概每秒调用15-20次。没有其他代码可能会在控制台上抛出 "undefined",也没有任何写入数据库的代码。
为什么会这样?我该怎么做才能妥善处理它?
编辑 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
尚未完成写入的文件。
似乎node-persist
处理并发读写不可靠。
如果在执行 setItem
时调用 getItem
,则会抛出此错误。
唯一的解决方案是,这由库修复,或者您确保在 setItem
.
时永远不会调用 getItem
我的建议是将与该存储相关的所有内容打包到一个自己的 class 中。这样您以后就可以轻松地用另一个库替换它。
我填了一个issue:
Concurrent setItem
and getItem
can lead into an unahdled does not look like a valid storage file
再补充一点@t.niese 所说的内容,库基本上没有提供并发性。解决方案之一是序列化对库的调用。下面是序列化对库的所有调用的代码示例。
另外,给定的库将每个键值对写入一个文件。我认为序列化每个键的调用会提供更好的吞吐量。
说了这么多,这应该是在图书馆处理的。
注释和取消注释选择存储到 node-persist 或围绕 node-persist 的包装器。
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)
})
我有一个重节点应用程序,我正在使用 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;
}
}
}
}
这段代码在长函数中有点深。一切都很简单。但是有两个问题:
uid
通常是undefined
。我的猜测是该文件尚未保存,因此当我尝试对其进行 getItem 时,它具有未定义的值。即使if (uid == 'undefined')
,console.log(uid)
仍然会抛出许多undefined
。我不明白为什么,因为我是 "returning".
代码就是这样。这个if
大概每秒调用15-20次。没有其他代码可能会在控制台上抛出 "undefined",也没有任何写入数据库的代码。
为什么会这样?我该怎么做才能妥善处理它?
编辑 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
尚未完成写入的文件。
似乎node-persist
处理并发读写不可靠。
如果在执行 setItem
时调用 getItem
,则会抛出此错误。
唯一的解决方案是,这由库修复,或者您确保在 setItem
.
getItem
我的建议是将与该存储相关的所有内容打包到一个自己的 class 中。这样您以后就可以轻松地用另一个库替换它。
我填了一个issue:
Concurrent setItem
and getItem
can lead into an unahdled does not look like a valid storage file
再补充一点@t.niese 所说的内容,库基本上没有提供并发性。解决方案之一是序列化对库的调用。下面是序列化对库的所有调用的代码示例。
另外,给定的库将每个键值对写入一个文件。我认为序列化每个键的调用会提供更好的吞吐量。
说了这么多,这应该是在图书馆处理的。
注释和取消注释选择存储到 node-persist 或围绕 node-persist 的包装器。
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)
})