"Метеоритный код должен всегда выполняться в волокне" при использовании Meteor.runAsync
Использование кассандры с метеором.
let client = new cassandra.Client({contactPoints: [cassandraHost]});
var cassandraExecSync = Meteor.wrapAsync(client.execute, client);
MyProject.Feed.CassandraMeteorWrap = {
insertNewPost: function (userId, postContentJson, relevance) {
var insertCommand = insert(userId, postContentJson, relevance);
try {
return cassandraExecSync(insertCommand);
} catch (err) {
console.log("error inserting: " + insertCommand);
console.log(err);
}
}
Таким образом, я обернул Cassandra.client.execute (который имеет последний аргумент в качестве обратного вызова) с Meteor.wrapAsync
Первые несколько вставок работают, но после нескольких вставок (вставка вызывается периодически) я получаю:
[Ошибка: Метеоритный код всегда должен работать внутри волокна. Попробуйте обернуть обратные вызовы, которые вы передаете в неметеорные библиотеки, с помощью Meteor.bindEnvironment.]
Обновление: Метеор отладки показал трассировку стека, и исключение начинается с пакета npm, который я использую "cassandra-driver" в.onTimeout():
function listOnTimeout() {
var msecs = this.msecs;
var list = this;
debug('timeout callback ' + msecs);
var now = Timer.now();
debug('now: %d', now);
var first;
while (first = L.peek(list)) {
// If the previous iteration caused a timer to be added,
// update the value of "now" so that timing computations are
// done correctly. See test/simple/test-timers-blocking-callback.js
// for more information.
if (now < first._monotonicStartTime) {
now = Timer.now();
debug('now: %d', now);
}
var diff = now - first._monotonicStartTime;
if (diff < msecs) {
list.start(msecs - diff, 0);
debug(msecs + ' list wait because diff is ' + diff);
return;
} else {
L.remove(first);
assert(first !== L.peek(list));
if (!first._onTimeout) continue;
// v0.4 compatibility: if the timer callback throws and the
// domain or uncaughtException handler ignore the exception,
// other timers that expire on this tick should still run.
//
// https://github.com/joyent/node/issues/2631
var domain = first.domain;
if (domain && domain._disposed) continue;
try {
if (domain)
domain.enter();
var threw = true;
**first._onTimeout();**
if (domain)
domain.exit();
threw = false;
} finally {
if (threw) {
// We need to continue processing after domain error handling
// is complete, but not by using whatever domain was left over
// when the timeout threw its exception.
var oldDomain = process.domain;
process.domain = null;
process.nextTick(function() {
list.ontimeout();
});
process.domain = oldDomain;
}
}
}
}
debug(msecs + ' list empty');
assert(L.isEmpty(list));
list.close();
delete lists[msecs];
}