Thanks. I’d already started similar from looking at the source for fetch in mini mongo. I’ve padded it out to a function. Some bits are specific to my codebase (inf for console logging) but may be useful to others.
// Fetch data from a mongo cursor with a timeout
function fetchWithTimeout(curs: Mongo.Cursor<any>, collectionName: string, searchCriteria: any, searchProjection: any, inf: LogInfoData, timeout=30000 ): any[] {
let intervalHandle: number;
let retval: any;
let cancelFetch=false;
const stime=moment();
try {
intervalHandle = Meteor.setInterval( () => {
const dur = moment().diff(stime, 'ms');
consoledebug(inf.pre, "LONG fetch operation still running after "+dur+"ms:", collectionName, JSON.stringify(searchCriteria));
if (dur>timeout) {
if (intervalHandle) { Meteor.clearInterval(intervalHandle); }
cancelFetch=true;
consoleerror(inf.pre, "Fetch timed out: collection:", collectionName, "searchCriteria:", JSON.stringify(searchCriteria), "searchProjection:", searchProjection );
throwMeteorError(inf, "Failed to execute find (timed out) against the collection: "+collectionName);
}
}, 5000);
// Fetch the data from the mongo cursor
retval=[];
curs.forEach( (doc: any) => {
retval.push(doc);
if (cancelFetch) {
if (intervalHandle) { Meteor.clearInterval(intervalHandle); }
consoleerror(inf.pre, "Fetch loop timed out: collection:", collectionName, "searchCriteria:", JSON.stringify(searchCriteria), "searchProjection:", searchProjection );
throwMeteorError(inf, "Failed to execute fetch (timed out) against the collection: "+collectionName);
}
});
if (intervalHandle) { Meteor.clearInterval(intervalHandle); }
return retval;
} catch (error) {
if (intervalHandle) { Meteor.clearInterval(intervalHandle); }
consoleerror(inf.pre, "Fetch loop exception: collection:", collectionName, "searchCriteria:", JSON.stringify(searchCriteria), "searchProjection:", searchProjection );
throwMeteorError(inf, "Fetch loop exception against the collection: "+collectionName);
}
if (intervalHandle) { Meteor.clearInterval(intervalHandle); }
consoleerror(inf.pre, "Fetch loop unknown error: collection:", collectionName, "searchCriteria:", JSON.stringify(searchCriteria), "searchProjection:", searchProjection );
throwMeteorError(inf, "Fetch loop unknown error against the collection: "+collectionName);
}
The usage of this function is:
const data = fetchWithTimeout((<any> ColPatients).find(searchCriteria, searchProjection),
collectionName, searchCriteria, searchProjection, inf);
Basically do a find to get the cursor and pass it to the function. The other parameters are for logging context specific errors to assist in debugging