我正在使用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变量有访问权限怎么办?
什么是解决这个问题的更好方法?
谢谢!
1 回答
如果我找对你,你只是希望你的选票过期并在一段时间后被销毁?
如果你使用mongoose,你可以添加一个'expires'字段,因此不再需要你的代码 .
例如,如果您希望您的投票仅在一天内有效,您可以执行以下操作: