我在nodejs中使用mongoDB更改流,一切正常,但是如果数据库关闭花费了10到5秒钟以上的时间来使更改流抛出超时错误,这是我的更改流观察者代码
Service.prototype.watcher = function( db ){
let collection = db.collection('tokens');
let changeStream = collection.watch({ fullDocument: 'updateLookup' });
let resumeToken, newChangeStream;
changeStream.on('change', next => {
resumeToken = next._id;
console.log('data is ', JSON.stringify(next))
changeStream.close();
// console.log('resumeToken is ', JSON.stringify(resumeToken))
newChangeStream = collection.watch({ resumeAfter : resumeToken });
newChangeStream.on('change', next => {
console.log('insert called ', JSON.stringify( next ))
});
});
但是在数据库端,我已经处理了它,也就是说,如果数据库已关闭或通过使用此代码重新连接
this.db.on('reconnected', function () {
console.info('MongoDB reconnected!');
});
this.db.on('disconnected', function() {
console.warn('MongoDB disconnected!');
});
但是我无法处理变更流观察程序以在数据库关闭时将其停止,并在重新连接数据库时或者是否还有其他更好的方法来重新启动它?
答案 0 :(得分:1)
您想要做的是将watch()
调用封装在一个函数中。然后,此函数将在错误时自行调用,以使用先前保存的恢复令牌重新监视集合。您的代码缺少的是错误处理程序。例如:
const MongoClient = require('mongodb').MongoClient
const uri = 'mongodb://localhost:27017/test?replicaSet=replset'
var resume_token = null
run()
function watch_collection(con, db, coll) {
console.log(new Date() + ' watching: ' + coll)
con.db(db).collection(coll).watch({resumeAfter: resume_token})
.on('change', data => {
console.log(data)
resume_token = data._id
})
.on('error', err => {
console.log(new Date() + ' error: ' + err)
watch_collection(con, coll)
})
}
async function run() {
con = await MongoClient.connect(uri, {"useNewUrlParser": true})
watch_collection(con, 'test', 'test')
}
请注意,watch_collection()
包含watch()
方法及其处理程序。更改时,它将打印更改并存储恢复令牌。出错时,它会再次调用自己以重新监视集合。
答案 1 :(得分:0)
这是我开发的解决方案,只需添加stream.on(error)函数,这样它就不会在出现错误时崩溃,因为在重新连接数据库时重新启动流,还为每个事件将恢复令牌保存在文件中,这是当应用程序崩溃或停止并且再次运行时很有用,并且在此期间,如果添加了x条记录,那么在应用程序重新启动时,只需从文件中获取最后一个恢复令牌,然后从那里启动观察程序,它将在此之后插入所有记录,因此没有记录将丢失,这是下面的代码
var rsToken ;
try {
rsToken = await this.getResumetoken()
} catch (error) {
rsToken = null ;
}
if (!rsToken)
changeStream = collection.watch({ fullDocument: 'updateLookup' });
else
changeStream = collection.watch({ fullDocument: 'updateLookup', resumeAfter : rsToken });
changeStream.on('change', next => {
resumeToken = next._id;
THIS.saveTokenInfile(resumeToken)
cs_processor.process( next )
});
changeStream.on('error', err => {
console.log('changestream error ')
})