我正在使用NodeJS,Mongodb和Mariadb开发一个应用程序。 用户可以为某些操作创建投票。它们在特定时间内有效。 为了控制投票是否有效,我将它们及其创建时间存储在一个集合中,并对“最旧”的投票开始超时,因为该投票将首先过期。 因此,如果超时结束,投票将被删除,而下一个投票(如果存储了一个)将创建一个超时。如果没有表决权,则什么也不会发生。 因此,我需要以某种方式检查超时是否正在运行,因此我只需要向数据库添加投票,或者是否还需要创建超时。更具体地说,如果数据库中没有条目,则需要启动超时。但是在mongodb中进行此查找并不安全,因为没有“事务”。
这是我的方法,但我认为这并不安全: 我有一个索引文件:
let timeoutRunning = false;
activateTimeout = ()=>{timeoutRunning=true;}
deactivateTimeout = ()=>{timeoutRunning=false;}
module.exports = [timeout, activateTimeout, deactivateTimeout]
在另一个文件中:
const index = require("index.js");
const Vote = require("voteModel.js");
router.post("/createVote", (req, res)=>{
//some other stuff
let v = new Vote({voteId:1, type:0, iat:Date.now()})
Vote.insertVote(v)
.then((item)=>{
console.log("adding vote ", v.voteId)
//only set Timeout if there is no running
if(!index.timeoutRunning){ // is index.timeoutRunning just a copy?
index.activateTimeout();
console.log(" creating timeout for vote ",v.voteId)
setTimeout(()=>{handleExpiredVote(v.voteId, v.type)}, 100000)
}
})
.catch((err)=>{
console.log(err)
})
})
handleExpiredVote = (voteId, type)=>{
Vote.deleteVote(voteId).exec()
.then((status)=>{
console.log(status)
console.log("Deleting Vote ", voteId)
return Vote.getNextVote().exec()
})
.then((nextVote)=>{
if(nextVote!= null){
console.log("NEXT, creating timeout for vote ",nextVote.voteId)
setTimeout(()=>{handleExpiredVote(nextVote.voteId,
nextVote.type)}, 1000)
}else{
console.log("no votes left")
index.deactivateTimeout();
}
})
.catch((err)=>{
console.log(err)
})
我知道NodeJS是单线程的。但是这个想法安全吗?如果在执行另一个调用的activateTimeout函数之前,对timeoutRunning变量具有访问权限怎么办?
有什么更好的方法来解决这个问题?
谢谢!
答案 0 :(得分:0)
如果我说对了,您只是想让选票过期并在一段时间后被销毁?
如果使用猫鼬,则只需添加一个“ expires”字段,这样就不需要更多代码了。
例如,如果您希望您的投票只有一天有效,则可以执行以下操作:
const VoteSchema = new mongoose.Schema({
name: String,
createdAt: { type: Date, expires: '1d' }
});