NodeJS.handleMessage() J2V8 зависает для некоторых функций JS.
С помощью:
- j2v8 4.6
- JDK 1.8
- Win7 x64
Я обнаружил, что запуск простой JS-функции с использованием NodeJS J2V8 работает нормально, в то время как более сложная функция дает сбой. Ява выглядит так:
public void testGetUser4() throws IOException, ScriptException {
String scriptFilename = "UserManagement.js";
String script = loadFile(scriptFilename);
NodeJS nodeJS = NodeJS.createNodeJS();
V8Object exports = nodeJS.require(new File(scriptFilename));
JavaCallback callback = new JavaCallback() {
// @Override
public Object invoke(final V8Object receiver, final V8Array parameters) {
System.out.println("Callback invoked.");
return null;
}
};
V8Function function = new V8Function(nodeJS.getRuntime(), callback);
V8Object event = new V8Object(nodeJS.getRuntime());
event = event.add("user_id", "1755ac52-94c7-11e7-b9f8-0adfa8abb906");
exports.executeJSFunction("_get_user2", event, function);
runMessageLoop(nodeJS);
event.release();
function.release();
exports.release();
nodeJS.release();
System.out.println("Done.");
}
private void runMessageLoop(NodeJS nodeJS) {
int cnt = 0;
while (nodeJS.isRunning()) {
boolean res = nodeJS.handleMessage();
System.out.println("Result for message " + cnt++ + " is " + res);
}
}
Простая функция JS:
exports._get_user2 = function(event, callback) {
console.log('Event: ', JSON.stringify(event, null, '\t'));
var userId = event.user_id;
console.log('Searching for user with id: ', userId);
callback(null, userId);
console.log('JS function complete.');
};
Тест успешно завершен с этим выводом:
Event: {
"user_id": "1755ac52-94c7-11e7-b9f8-0adfa8abb906"
}
Searching for user with id: 1755ac52-94c7-11e7-b9f8-0adfa8abb906
Callback invoked.
JS function complete.
Result for message 0 is true
Result for message 1 is false
Done.
Но когда я расширяю эту функцию JS с помощью вызова mysql, тест не завершается. Функция:
exports._get_user = function(event, callback) {
console.log('Event: ', JSON.stringify(event, null, '\t'));
var userId = event.user_id;
console.log('Searching for user with id: ', userId);
var sql = "call usermanagement.get_user(?)";
pool.query(sql, userId, function(error, results, fields) {
if (error) {
console.log("JS function failed", error);
callback(error);
} else {
var res = '{}';
if (results[0].length != 0) {
res = results[0][0];
}
console.log(res);
callback(null, res);
}
});
console.log('JS function complete.');
};
Теперь кажется, что тест выполняет весь код, но никогда не возвращается из метода runMessageLoop():
Event: {
"user_id": "1755ac52-94c7-11e7-b9f8-0adfa8abb906"
}
Searching for user with id: 1755ac52-94c7-11e7-b9f8-0adfa8abb906
JS function complete.
Result for message 0 is true
Result for message 1 is true
Result for message 2 is true
Result for message 3 is true
Result for message 4 is true
Result for message 5 is true
Result for message 6 is true
Result for message 7 is true
{}
Callback invoked.
Result for message 8 is true
Result for message 9 is true
Result for message 10 is true
Result for message 11 is true
(no more output and the test doesn't complete.)
Amazon AWS, похоже, столкнулся с аналогичной проблемой, реализуя узел нод службы AWS Lambda, и некоторые используют 'context.callbackWaitsForEmptyEventLoop = false'
в лямбдах, чтобы обойти это. Но Amazon указывает, что это следует использовать только в качестве крайней меры.
Я делаю что-то неправильно?