显然setInterval 和拉取数据库似乎是最简单的方法。下面的解决方案可以被视为数据库启动这些计划事件的替代方案,因此您将获得 push 而不是 pull 方法。
假设您有一个简单的集合 scheduledEvents,其中包含一个 ISODate 类型的字段 scheduledAt,例如:
{ "_id" : ObjectId("5c457cb554651d56ffe0c759"), "scheduledAt" : ISODate("2019-01-21T08:03:01.129Z") }
然后您可以在该集合上创建TTL index。基本上这个想法是当 scheduledAt 成为过去的日期时,MongoDB 数据库服务器将定期删除这些文档。
db.scheduledEvents.createIndex( { "scheduledAt": 1 }, { expireAfterSeconds: 30} )
幕后有一个在数据库服务器上运行的计划作业,它查询并删除所有这些文档。文件不会立即被删除 - 会有一点延迟,但您应该可以接受。
现在您有了一种调度机制,因此您需要做的就是从您的代码中订阅这些事件。为此,您可以利用Change Streams。
要使用它们,您必须将数据库作为副本集运行(可以是 standalone replica set)。然后在您的应用程序代码中,您可以使用以下代码订阅 scheduledEvents 集合:
const changeStreamCursor = db.scheduledEvents.watch();
function pollStream(cursor) {
while (!cursor.isExhausted()) {
if (cursor.hasNext()) {
var change = cursor.next();
if(change.operationType === "delete"){
// your logic goes here
}
}
}
pollStream(cursor);
}
pollStream(changeStreamCursor);
显然scheduledEvents 集合可以包含与您的业务逻辑相关的其他字段,并且可以在您的更改流侦听器中访问这些字段。