mirror of https://gitee.com/bigwinds/arangodb
Cleaning up the ifs....Greatly simplifying testing.js
This commit is contained in:
parent
91df9e36b2
commit
49a3d3e018
|
@ -446,190 +446,58 @@ function analyzeCoreDumpWindows(instanceInfo) {
|
||||||
executeExternalAndWait("cdb", args);
|
executeExternalAndWait("cdb", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
function checkInstanceAlive(instanceInfo, options) {
|
||||||
/// @brief checks of an instance is still alive
|
return instanceInfo.arangods.reduce((previous, arangod) => {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
if (arangod.hasOwnProperty('exitStatus')) {
|
||||||
|
return false;
|
||||||
function checkInstanceAliveSingleServer(instanceInfo, options) {
|
|
||||||
if (instanceInfo.hasOwnProperty('exitStatus')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = statusExternal(instanceInfo.pid, false);
|
|
||||||
const ret = res.status === "RUNNING";
|
|
||||||
|
|
||||||
if (!ret) {
|
|
||||||
print("ArangoD with PID " + instanceInfo.pid.pid + " gone:");
|
|
||||||
print(instanceInfo);
|
|
||||||
|
|
||||||
if (res.hasOwnProperty('signal') &&
|
|
||||||
((res.signal === 11) ||
|
|
||||||
(res.signal === 6) ||
|
|
||||||
// Windows sometimes has random numbers in signal...
|
|
||||||
(platform.substr(0, 3) === 'win')
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
const storeArangodPath = "/var/tmp/arangod_" + instanceInfo.pid.pid;
|
|
||||||
|
|
||||||
print("Core dump written; copying arangod to " +
|
|
||||||
instanceInfo.tmpDataDir + " for later analysis.");
|
|
||||||
|
|
||||||
let corePath = (options.coreDirectory === "") ?
|
|
||||||
"core" :
|
|
||||||
options.coreDirectory + "/core*" + instanceInfo.pid.pid + "*'";
|
|
||||||
|
|
||||||
res.gdbHint = "Run debugger with 'gdb " +
|
|
||||||
storeArangodPath + " " + corePath;
|
|
||||||
|
|
||||||
if (platform.substr(0, 3) === 'win') {
|
|
||||||
// Windows: wait for procdump to do its job...
|
|
||||||
statusExternal(instanceInfo.monitor, true);
|
|
||||||
analyzeCoreDumpWindows(instanceInfo);
|
|
||||||
} else {
|
|
||||||
fs.copyFile("bin/arangod", storeArangodPath);
|
|
||||||
analyzeCoreDump(instanceInfo, options, storeArangodPath, instanceInfo.pid.pid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
instanceInfo.exitStatus = res;
|
const res = statusExternal(arangod.pid, false);
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret) {
|
|
||||||
print("marking crashy");
|
|
||||||
serverCrashed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief checks if an agency instance is still alive
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
function checkInstanceAliveAgency(instanceInfo, options) {
|
|
||||||
if (instanceInfo.hasOwnProperty('exitStatus')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < options.agencySize; i++) {
|
|
||||||
const res = statusExternal(instanceInfo.pids[i], false);
|
|
||||||
const ret = res.status === "RUNNING";
|
const ret = res.status === "RUNNING";
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
print("ArangoD with PID " + instanceInfo.pids[i].pid + " gone:");
|
print("ArangoD with PID " + arangod.pid + " gone:");
|
||||||
print(instanceInfo);
|
print(arangod);
|
||||||
|
|
||||||
if (res.hasOwnProperty('signal') &&
|
if (res.hasOwnProperty('signal') &&
|
||||||
((res.signal === 11) ||
|
((res.signal === 11) ||
|
||||||
(res.signal === 6) ||
|
(res.signal === 6) ||
|
||||||
// Windows sometimes has random numbers in signal...
|
// Windows sometimes has random numbers in signal...
|
||||||
(platform.substr(0, 3) === 'win')
|
(platform.substr(0, 3) === 'win')
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
const storeArangodPath = "/var/tmp/arangod_" + instanceInfo.pids[i].pid;
|
const storeArangodPath = "/var/tmp/arangod_" + arangod.pid;
|
||||||
|
|
||||||
print("Core dump written; copying arangod to " +
|
print("Core dump written; copying arangod to " +
|
||||||
instanceInfo.tmpDataDir + " for later analysis.");
|
arangod.tmpDataDir + " for later analysis.");
|
||||||
|
|
||||||
let corePath = (options.coreDirectory === "") ?
|
let corePath = (options.coreDirectory === "") ?
|
||||||
"core" :
|
"core" :
|
||||||
options.coreDirectory + "/core*" + instanceInfo.pids[i].pid + "*'";
|
options.coreDirectory + "/core*" + arangod.pid + "*'";
|
||||||
|
|
||||||
res.gdbHint = "Run debugger with 'gdb " +
|
res.gdbHint = "Run debugger with 'gdb " +
|
||||||
storeArangodPath + " " + corePath;
|
storeArangodPath + " " + corePath;
|
||||||
|
|
||||||
if (platform.substr(0, 3) === 'win') {
|
if (platform.substr(0, 3) === 'win') {
|
||||||
// Windows: wait for procdump to do its job...
|
// Windows: wait for procdump to do its job...
|
||||||
statusExternal(instanceInfo.monitor, true);
|
statusExternal(arangod.monitor, true);
|
||||||
analyzeCoreDumpWindows(instanceInfo);
|
analyzeCoreDumpWindows(arangod);
|
||||||
} else {
|
} else {
|
||||||
fs.copyFile("bin/arangod", storeArangodPath);
|
fs.copyFile("bin/arangod", storeArangodPath);
|
||||||
analyzeCoreDump(instanceInfo, options, storeArangodPath, instanceInfo.pids[i].pid);
|
analyzeCoreDump(arangod, options, storeArangodPath, arangod.pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instanceInfo.exitStatus === undefined) {
|
arangod.exitStatus = res;
|
||||||
instanceInfo.exitStatus = [];
|
|
||||||
}
|
|
||||||
instanceInfo.exitStatus[i] = res;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (instanceInfo.exitStatus !== undefined) {
|
if (!ret) {
|
||||||
print("marking crashy");
|
print("marking crashy");
|
||||||
serverCrashed = true;
|
serverCrashed = true;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkRemoteInstance(pid, wait, options) {
|
|
||||||
const debug = options.debug || false;
|
|
||||||
const p = JSON.stringify(pid);
|
|
||||||
|
|
||||||
const res = JSON.parse(arango.PUT("/_admin/execute",
|
|
||||||
`return require("internal").statusExternal(${p}, ${wait});`));
|
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
print(`status of remote process ${p}: ${res.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkInstanceAliveCluster(instanceInfo, options) {
|
|
||||||
let clusterFit = true;
|
|
||||||
|
|
||||||
for (let pid in instanceInfo.pids) {
|
|
||||||
if (instanceInfo.pids.hasOwnProperty(pid)) {
|
|
||||||
const checkpid = instanceInfo.pids[pid];
|
|
||||||
const ress = checkRemoteInstance(checkpid, false, options);
|
|
||||||
|
|
||||||
if (ress.hasOwnProperty('signal') &&
|
|
||||||
((ress.signal === 11) || (ress.signal === 6))) {
|
|
||||||
const storeArangodPath = "/var/tmp/arangod_" + checkpid.pid;
|
|
||||||
|
|
||||||
print("Core dump written; copying arangod to " +
|
|
||||||
storeArangodPath + " for later analysis.");
|
|
||||||
|
|
||||||
ress.gdbHint = "Run debugger with 'gdb " +
|
|
||||||
storeArangodPath +
|
|
||||||
" /var/tmp/core*" + checkpid.pid + "*'";
|
|
||||||
|
|
||||||
if (platform.substr(0, 3) === 'win') {
|
|
||||||
// Windows: wait for procdump to do its job...
|
|
||||||
checkRemoteInstance(instanceInfo.monitor, true, options);
|
|
||||||
analyzeCoreDumpWindows(instanceInfo);
|
|
||||||
} else {
|
|
||||||
fs.copyFile("bin/arangod", storeArangodPath);
|
|
||||||
analyzeCoreDump(instanceInfo, options, storeArangodPath, checkpid.pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
instanceInfo.exitStatus = ress;
|
|
||||||
clusterFit = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (clusterFit) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
print("marking crashy");
|
|
||||||
serverCrashed = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkInstanceAlive(instanceInfo, options) {
|
|
||||||
if (options.cluster) {
|
|
||||||
return checkInstanceAliveCluster(instanceInfo, options);
|
|
||||||
}
|
|
||||||
if (options.agency) {
|
|
||||||
return checkInstanceAliveAgency(instanceInfo, options);
|
|
||||||
}
|
|
||||||
return checkInstanceAliveSingleServer(instanceInfo, options);
|
|
||||||
|
|
||||||
|
return ret && previous;
|
||||||
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1232,184 +1100,21 @@ function runArangoBenchmark(options, instanceInfo, cmds) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function shutdownInstance(instanceInfo, options) {
|
function shutdownInstance(instanceInfo, options) {
|
||||||
|
// mop: reversing for now because it seems cluster hangs when agency is killed first :S
|
||||||
|
// should be fixed :S
|
||||||
if (!checkInstanceAlive(instanceInfo, options)) {
|
if (!checkInstanceAlive(instanceInfo, options)) {
|
||||||
print("Server already dead, doing nothing. This shouldn't happen?");
|
print("Server already dead, doing nothing. This shouldn't happen?");
|
||||||
}
|
}
|
||||||
|
instanceInfo.arangods.reverse().forEach(arangod => {
|
||||||
if (options.valgrind) {
|
if (options.valgrind) {
|
||||||
waitOnServerForGC(instanceInfo, options, 60);
|
waitOnServerForGC(arangod, options, 60);
|
||||||
}
|
|
||||||
|
|
||||||
if (options.cluster) {
|
|
||||||
if (instanceInfo.exitStatus === undefined) {
|
|
||||||
instanceInfo.exitStatus = [];
|
|
||||||
}
|
}
|
||||||
// mop: currently it seems killing the agency first renders the other servers unusable :S
|
if (arangod.exitStatus === undefined) {
|
||||||
for (let i=instanceInfo.pids.length - 1;i>=0;i--) {
|
print(arangod.url + "/_admin/shutdown");
|
||||||
if (instanceInfo.exitStatus[i] === undefined) {
|
download(arangod.url + "/_admin/shutdown", "",
|
||||||
print(instanceInfo.urls[i] + "/_admin/shutdown");
|
|
||||||
download(instanceInfo.urls[i] + "/_admin/shutdown", "",
|
|
||||||
makeAuthorizationHeaders(options));
|
makeAuthorizationHeaders(options));
|
||||||
|
|
||||||
print("Waiting for server with pid " + instanceInfo.pids[i].pid + " to shut down");
|
print("Waiting for server with pid " + arangod.pid + " to shut down");
|
||||||
|
|
||||||
let count = 0;
|
|
||||||
let bar = "[";
|
|
||||||
|
|
||||||
let timeout = 600;
|
|
||||||
|
|
||||||
if (options.sanitizer) {
|
|
||||||
timeout *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instanceInfo.exitStatus === undefined) {
|
|
||||||
instanceInfo.exitStatus = [];
|
|
||||||
}
|
|
||||||
while (true) {
|
|
||||||
instanceInfo.exitStatus[i] = statusExternal(instanceInfo.pids[i], false);
|
|
||||||
|
|
||||||
if (instanceInfo.exitStatus[i].status === "RUNNING") {
|
|
||||||
++count;
|
|
||||||
|
|
||||||
if (options.valgrind) {
|
|
||||||
wait(1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count % 10 === 0) {
|
|
||||||
bar = bar + "#";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 600) {
|
|
||||||
print("forcefully terminating " + yaml.safeDump(instanceInfo.pids[i]) +
|
|
||||||
" after " + timeout + "s grace period; marking crashy.");
|
|
||||||
serverCrashed = true;
|
|
||||||
killExternal(instanceInfo.pids[i]);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
wait(1);
|
|
||||||
}
|
|
||||||
} else if (instanceInfo.exitStatus[i].status !== "TERMINATED") {
|
|
||||||
if (instanceInfo.exitStatus[i].hasOwnProperty('signal')) {
|
|
||||||
print("Server shut down with : " +
|
|
||||||
yaml.safeDump(instanceInfo.exitStatus[i]) +
|
|
||||||
" marking build as crashy.");
|
|
||||||
|
|
||||||
serverCrashed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (platform.substr(0, 3) === 'win') {
|
|
||||||
// Windows: wait for procdump to do its job...
|
|
||||||
statusExternal(instanceInfo.monitor, true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print("Server shutdown: Success.");
|
|
||||||
break; // Success.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 10) {
|
|
||||||
print("long Server shutdown: " + bar + ']');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print("Server already dead, doing nothing.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!options.skipLogAnalysis) {
|
|
||||||
instanceInfo.importantLogLines =
|
|
||||||
readImportantLogLines(instanceInfo.tmpDataDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// agency mode
|
|
||||||
else if (options.agency) {
|
|
||||||
if (instanceInfo.exitStatus === undefined) {
|
|
||||||
instanceInfo.exitStatus = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < options.agencySize; i++) {
|
|
||||||
if (instanceInfo.exitStatus[i] === undefined) {
|
|
||||||
download(instanceInfo.urls[i] + "/_admin/shutdown", "",
|
|
||||||
makeAuthorizationHeaders(options));
|
|
||||||
|
|
||||||
print("Waiting for server shut down");
|
|
||||||
|
|
||||||
let count = 0;
|
|
||||||
let bar = "[";
|
|
||||||
|
|
||||||
let timeout = 600;
|
|
||||||
|
|
||||||
if (options.sanitizer) {
|
|
||||||
timeout *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instanceInfo.exitStatus === undefined) {
|
|
||||||
instanceInfo.exitStatus = [];
|
|
||||||
}
|
|
||||||
while (true) {
|
|
||||||
instanceInfo.exitStatus[i] = statusExternal(instanceInfo.pids[i], false);
|
|
||||||
|
|
||||||
if (instanceInfo.exitStatus[i].status === "RUNNING") {
|
|
||||||
++count;
|
|
||||||
|
|
||||||
if (options.valgrind) {
|
|
||||||
wait(1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count % 10 === 0) {
|
|
||||||
bar = bar + "#";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 600) {
|
|
||||||
print("forcefully terminating " + yaml.safeDump(instanceInfo.pids[i]) +
|
|
||||||
" after " + timeout + "s grace period; marking crashy.");
|
|
||||||
serverCrashed = true;
|
|
||||||
killExternal(instanceInfo.pids[i]);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
wait(1);
|
|
||||||
}
|
|
||||||
} else if (instanceInfo.exitStatus[i].status !== "TERMINATED") {
|
|
||||||
if (instanceInfo.exitStatus[i].hasOwnProperty('signal')) {
|
|
||||||
print("Server shut down with : " +
|
|
||||||
yaml.safeDump(instanceInfo.exitStatus[i]) +
|
|
||||||
" marking build as crashy.");
|
|
||||||
|
|
||||||
serverCrashed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (platform.substr(0, 3) === 'win') {
|
|
||||||
// Windows: wait for procdump to do its job...
|
|
||||||
statusExternal(instanceInfo.monitor, true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print("Server shutdown: Success.");
|
|
||||||
break; // Success.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 10) {
|
|
||||||
print("long Server shutdown: " + bar + ']');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print("Server already dead, doing nothing.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!options.skipLogAnalysis) {
|
|
||||||
instanceInfo.importantLogLines =
|
|
||||||
readImportantLogLines(instanceInfo.tmpDataDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// single server
|
|
||||||
else {
|
|
||||||
if (typeof(instanceInfo.exitStatus) === 'undefined') {
|
|
||||||
download(instanceInfo.url + "/_admin/shutdown", "",
|
|
||||||
makeAuthorizationHeaders(options));
|
|
||||||
|
|
||||||
print("Waiting for server shut down");
|
|
||||||
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let bar = "[";
|
let bar = "[";
|
||||||
|
@ -1421,9 +1126,9 @@ function shutdownInstance(instanceInfo, options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
instanceInfo.exitStatus = statusExternal(instanceInfo.pid, false);
|
arangod.exitStatus = statusExternal(arangod.pid, false);
|
||||||
|
|
||||||
if (instanceInfo.exitStatus.status === "RUNNING") {
|
if (arangod.exitStatus.status === "RUNNING") {
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
if (options.valgrind) {
|
if (options.valgrind) {
|
||||||
|
@ -1436,26 +1141,26 @@ function shutdownInstance(instanceInfo, options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count > 600) {
|
if (count > 600) {
|
||||||
print("forcefully terminating " + yaml.safeDump(instanceInfo.pid) +
|
print("forcefully terminating " + yaml.safeDump(arangod.pid) +
|
||||||
" after " + timeout + "s grace period; marking crashy.");
|
" after " + timeout + "s grace period; marking crashy.");
|
||||||
serverCrashed = true;
|
serverCrashed = true;
|
||||||
killExternal(instanceInfo.pid);
|
killExternal(arangod.pid);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
wait(1);
|
wait(1);
|
||||||
}
|
}
|
||||||
} else if (instanceInfo.exitStatus.status !== "TERMINATED") {
|
} else if (arangod.exitStatus.status !== "TERMINATED") {
|
||||||
if (instanceInfo.exitStatus.hasOwnProperty('signal')) {
|
if (arangod.exitStatus.hasOwnProperty('signal')) {
|
||||||
print("Server shut down with : " +
|
print("Server shut down with : " +
|
||||||
yaml.safeDump(instanceInfo.exitStatus) +
|
yaml.safeDump(arangod.exitStatus) +
|
||||||
" marking build as crashy.");
|
" marking build as crashy.");
|
||||||
|
|
||||||
serverCrashed = true;
|
serverCrashed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (platform.substr(0, 3) === 'win') {
|
if (platform.substr(0, 3) === 'win') {
|
||||||
// Windows: wait for procdump to do its job...
|
// Windows: wait for procdump to do its job...
|
||||||
statusExternal(instanceInfo.monitor, true);
|
statusExternal(arangod.monitor, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print("Server shutdown: Success.");
|
print("Server shutdown: Success.");
|
||||||
|
@ -1471,65 +1176,13 @@ function shutdownInstance(instanceInfo, options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.skipLogAnalysis) {
|
if (!options.skipLogAnalysis) {
|
||||||
instanceInfo.importantLogLines =
|
arangod.importantLogLines =
|
||||||
readImportantLogLines(instanceInfo.tmpDataDir);
|
readImportantLogLines(arangod.rootDir);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
cleanupDirectories.push(instanceInfo.rootDir);
|
||||||
cleanupDirectories = cleanupDirectories.concat(
|
|
||||||
instanceInfo.tmpDataDir, instanceInfo.flatTmpDataDir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief starts a dispatcher
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/*
|
|
||||||
function startDispatcher(instanceInfo) {
|
|
||||||
let args = {};
|
|
||||||
|
|
||||||
args["configuration"] = "none";
|
|
||||||
|
|
||||||
args["cluster.agent-path"] = ETCD_ARANGO_BIN;
|
|
||||||
|
|
||||||
args["cluster.arangod-path"] = ARANGOD_BIN;
|
|
||||||
|
|
||||||
args["cluster.coordinator-config"] =
|
|
||||||
fs.join("etc", "relative", "arangod-coordinator.conf");
|
|
||||||
|
|
||||||
args["cluster.dbserver-config"] =
|
|
||||||
fs.join("etc", "relative", "arangod-dbserver.conf");
|
|
||||||
|
|
||||||
args["cluster.disable-dispatcher-frontend"] = "false";
|
|
||||||
|
|
||||||
args["cluster.disable-dispatcher-kickstarter"] = "false";
|
|
||||||
|
|
||||||
args["cluster.data-path"] = "cluster";
|
|
||||||
|
|
||||||
args["cluster.log-path"] = "cluster";
|
|
||||||
|
|
||||||
args["database.directory"] =
|
|
||||||
fs.join(instanceInfo.flatTmpDataDir, "dispatcher");
|
|
||||||
|
|
||||||
args["log.file"] =
|
|
||||||
fs.join(instanceInfo.flatTmpDataDir, "dispatcher.log");
|
|
||||||
|
|
||||||
args["server.endpoint"] = arango.getEndpoint();
|
|
||||||
|
|
||||||
args["javascript.startup-directory"] = "js";
|
|
||||||
|
|
||||||
args["javascript.app-path"] = fs.join("js", "apps");
|
|
||||||
|
|
||||||
instanceInfo.dispatcherPid = executeExternal(ARANGOD_BIN, toArgv(args));
|
|
||||||
|
|
||||||
while (arango.GET("/_admin/version").error === true) {
|
|
||||||
print("Waiting for dispatcher to appear");
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Dispatcher is ready");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief starts an instance
|
/// @brief starts an instance
|
||||||
///
|
///
|
||||||
|
@ -1537,28 +1190,25 @@ function startDispatcher(instanceInfo) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function startInstanceCluster(instanceInfo, protocol, options,
|
function startInstanceCluster(instanceInfo, protocol, options,
|
||||||
addArgs, testname, appDir, tmpDataDir) {
|
addArgs, name, rootDir) {
|
||||||
instanceInfo.urls = [];
|
|
||||||
let clusterArgs = options._extraArgs || {};
|
let clusterArgs = options._extraArgs || {};
|
||||||
|
|
||||||
let makeArgs = function(name, args) {
|
let makeArgs = function(name, args) {
|
||||||
args = args || options.extraArgs;
|
args = args || options.extraArgs;
|
||||||
|
|
||||||
let appDir = fs.join(tmpDataDir, name + '-apps');
|
let subDir = fs.join(rootDir, name);
|
||||||
fs.makeDirectoryRecursive(appDir);
|
fs.makeDirectoryRecursive(subDir);
|
||||||
|
|
||||||
let tmpDir = fs.join(tmpDataDir, name + '-tmp');
|
let subArgs = makeArgsArangod(options, fs.join(subDir, "apps"));
|
||||||
fs.makeDirectoryRecursive(tmpDir);
|
|
||||||
|
|
||||||
let subArgs = makeArgsArangod(options, appDir);
|
|
||||||
subArgs = _.extend(subArgs, args);
|
subArgs = _.extend(subArgs, args);
|
||||||
|
|
||||||
return [subArgs, testname + '-' + 'agency', appDir, tmpDir];
|
return [subArgs, name, subDir];
|
||||||
}
|
}
|
||||||
options.agencySize = 1;
|
|
||||||
startInstanceAgency(instanceInfo, protocol, options, ...makeArgs('agency', clusterArgs));
|
|
||||||
|
|
||||||
let agencyEndpoint = instanceInfo.endpoints[0];
|
options.agencySize = 1;
|
||||||
|
startInstanceAgency(instanceInfo, protocol, options, ...makeArgs('agency', {}));
|
||||||
|
|
||||||
|
let agencyEndpoint = instanceInfo.endpoint;
|
||||||
let i;
|
let i;
|
||||||
for (i=0;i<options.clusterNodes;i++) {
|
for (i=0;i<options.clusterNodes;i++) {
|
||||||
let endpoint = protocol + "://127.0.0.1:" + findFreePort();
|
let endpoint = protocol + "://127.0.0.1:" + findFreePort();
|
||||||
|
@ -1570,10 +1220,6 @@ function startInstanceCluster(instanceInfo, protocol, options,
|
||||||
primaryArgs['cluster.agency-endpoint'] = agencyEndpoint;
|
primaryArgs['cluster.agency-endpoint'] = agencyEndpoint;
|
||||||
|
|
||||||
startInstanceSingleServer(instanceInfo, protocol, options, ...makeArgs('dbserver' + i, primaryArgs));
|
startInstanceSingleServer(instanceInfo, protocol, options, ...makeArgs('dbserver' + i, primaryArgs));
|
||||||
instanceInfo.endpoints.push(instanceInfo.endpoint);
|
|
||||||
instanceInfo.ports.push(instanceInfo.port);
|
|
||||||
instanceInfo.pids.push(instanceInfo.pid);
|
|
||||||
instanceInfo.urls.push(instanceInfo.url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let endpoint = protocol + "://127.0.0.1:" + findFreePort();
|
let endpoint = protocol + "://127.0.0.1:" + findFreePort();
|
||||||
|
@ -1586,26 +1232,7 @@ function startInstanceCluster(instanceInfo, protocol, options,
|
||||||
|
|
||||||
startInstanceSingleServer(instanceInfo, protocol, options, ...makeArgs('coordinator', coordinatorArgs));
|
startInstanceSingleServer(instanceInfo, protocol, options, ...makeArgs('coordinator', coordinatorArgs));
|
||||||
|
|
||||||
instanceInfo.endpoints.push(instanceInfo.endpoint);
|
let coordinatorUrl = instanceInfo.url;
|
||||||
instanceInfo.ports.push(instanceInfo.port);
|
|
||||||
instanceInfo.pids.push(instanceInfo.pid);
|
|
||||||
instanceInfo.urls.push(instanceInfo.url);
|
|
||||||
delete instanceInfo.endpoint;
|
|
||||||
delete instanceInfo.port;
|
|
||||||
delete instanceInfo.pid;
|
|
||||||
delete instanceInfo.url;
|
|
||||||
|
|
||||||
let notYetUp = instanceInfo.endpoints.slice();
|
|
||||||
while (notYetUp.length > 0) {
|
|
||||||
notYetUp = notYetUp.filter(notYet => {
|
|
||||||
let url = endpointToURL(notYet);
|
|
||||||
const reply = download(url + "/_api/version", "", makeAuthorizationHeaders(options));
|
|
||||||
return reply.code !== 200;
|
|
||||||
});
|
|
||||||
wait(0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
let coordinatorUrl = endpointToURL(instanceInfo.endpoints[instanceInfo.endpoints.length - 1]);
|
|
||||||
let response;
|
let response;
|
||||||
let httpOptions = makeAuthorizationHeaders(options);
|
let httpOptions = makeAuthorizationHeaders(options);
|
||||||
httpOptions.method = 'POST';
|
httpOptions.method = 'POST';
|
||||||
|
@ -1614,7 +1241,7 @@ function startInstanceCluster(instanceInfo, protocol, options,
|
||||||
response = download(coordinatorUrl + '/_admin/cluster/bootstrapDbServers', '{"isRelaunch":false}', httpOptions);
|
response = download(coordinatorUrl + '/_admin/cluster/bootstrapDbServers', '{"isRelaunch":false}', httpOptions);
|
||||||
|
|
||||||
while (response.code !== 200) {
|
while (response.code !== 200) {
|
||||||
console.log('bootstrap dbservers failed');
|
console.log('bootstrap dbservers failed', response);
|
||||||
wait(1);
|
wait(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1633,72 +1260,14 @@ function startInstanceCluster(instanceInfo, protocol, options,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function startInstanceAgency(instanceInfo, protocol, options,
|
function startArango(protocol, options, addArgs, name, rootDir) {
|
||||||
addArgs, testname, appDir, tmpDataDir) {
|
const dataDir = fs.join(rootDir, "data");
|
||||||
const N = options.agencySize;
|
const appDir = fs.join(rootDir, "apps");
|
||||||
const ports = [];
|
|
||||||
for (let i = 0; i < N; i++) {
|
|
||||||
ports.push(findFreePort());
|
|
||||||
}
|
|
||||||
instanceInfo.ports = ports;
|
|
||||||
|
|
||||||
const endpoints = ports.map(function(port) {
|
fs.makeDirectoryRecursive(dataDir);
|
||||||
return protocol + "://127.0.0.1:" + port;
|
fs.makeDirectoryRecursive(appDir);
|
||||||
});
|
|
||||||
instanceInfo.endpoints = endpoints;
|
|
||||||
|
|
||||||
let td = ports.map(function(port) {
|
|
||||||
return fs.join(tmpDataDir, "data" + port);
|
|
||||||
});
|
|
||||||
for (let i = 0; i < N; i++) {
|
|
||||||
fs.makeDirectoryRecursive(td[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let argss = [];
|
|
||||||
for (let i = 0; i < N; i++) {
|
|
||||||
let args = makeArgsArangod(options, appDir);
|
|
||||||
args["server.endpoint"] = endpoints[i];
|
|
||||||
args["database.directory"] = td[i];
|
|
||||||
args["log.file"] = fs.join(tmpDataDir, "log" + ports[i]);
|
|
||||||
args["agency.id"] = String(i);
|
|
||||||
args["agency.size"] = String(N);
|
|
||||||
|
|
||||||
if (protocol === "ssl") {
|
|
||||||
args["server.keyfile"] = fs.join("UnitTests", "server.pem");
|
|
||||||
}
|
|
||||||
|
|
||||||
args = _.extend(args, options.extraArgs);
|
|
||||||
|
|
||||||
if (addArgs !== undefined) {
|
|
||||||
args = _.extend(args, addArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i === N - 1) {
|
|
||||||
let l = [];
|
|
||||||
for (let j = 0; j < N; j++) {
|
|
||||||
l.push("--agency.endpoint");
|
|
||||||
l.push(endpoints[j]);
|
|
||||||
}
|
|
||||||
l.push("--agency.notify");
|
|
||||||
l.push("true");
|
|
||||||
|
|
||||||
args["flatCommands"] = l;
|
|
||||||
}
|
|
||||||
argss.push(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
instanceInfo.pids = [];
|
|
||||||
for (let i = 0; i < N; i++) {
|
|
||||||
instanceInfo.pids[i] = executeValgrind(ARANGOD_BIN, toArgv(argss[i]), options, testname);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function startInstanceSingleServer(instanceInfo, protocol, options,
|
|
||||||
addArgs, testname, appDir, tmpDataDir) {
|
|
||||||
let args = makeArgsArangod(options, appDir);
|
let args = makeArgsArangod(options, appDir);
|
||||||
|
|
||||||
let endpoint;
|
let endpoint;
|
||||||
let port;
|
let port;
|
||||||
if (!addArgs["server.endpoint"]) {
|
if (!addArgs["server.endpoint"]) {
|
||||||
|
@ -1708,15 +1277,14 @@ function startInstanceSingleServer(instanceInfo, protocol, options,
|
||||||
endpoint = addArgs["server.endpoint"];
|
endpoint = addArgs["server.endpoint"];
|
||||||
port = endpoint.split(":").pop();
|
port = endpoint.split(":").pop();
|
||||||
}
|
}
|
||||||
|
let instanceInfo = {};
|
||||||
instanceInfo.port = port;
|
instanceInfo.port = port;
|
||||||
instanceInfo.endpoint = endpoint;
|
instanceInfo.endpoint = endpoint;
|
||||||
|
instanceInfo.rootDir = rootDir;
|
||||||
let td = fs.join(tmpDataDir, "data");
|
|
||||||
fs.makeDirectoryRecursive(td);
|
|
||||||
|
|
||||||
args["server.endpoint"] = endpoint;
|
args["server.endpoint"] = endpoint;
|
||||||
args["database.directory"] = td;
|
args["database.directory"] = dataDir;
|
||||||
args["log.file"] = fs.join(tmpDataDir, "log");
|
args["log.file"] = fs.join(rootDir, "log");
|
||||||
|
|
||||||
if (protocol === "ssl") {
|
if (protocol === "ssl") {
|
||||||
args["server.keyfile"] = fs.join("UnitTests", "server.pem");
|
args["server.keyfile"] = fs.join("UnitTests", "server.pem");
|
||||||
|
@ -1727,67 +1295,16 @@ function startInstanceSingleServer(instanceInfo, protocol, options,
|
||||||
if (addArgs !== undefined) {
|
if (addArgs !== undefined) {
|
||||||
args = _.extend(args, addArgs);
|
args = _.extend(args, addArgs);
|
||||||
}
|
}
|
||||||
instanceInfo.pid = executeValgrind(ARANGOD_BIN, toArgv(args), options, testname);
|
instanceInfo.url = endpointToURL(instanceInfo.endpoint);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function startInstance(protocol, options, addArgs, testname, tmpDir) {
|
|
||||||
const startTime = time();
|
const startTime = time();
|
||||||
|
instanceInfo.pid = executeValgrind(ARANGOD_BIN, toArgv(args), options, name).pid;
|
||||||
|
|
||||||
let instanceInfo = {};
|
|
||||||
instanceInfo.topDir = TOP_DIR;
|
|
||||||
|
|
||||||
// create temporary directories
|
|
||||||
instanceInfo.flatTmpDataDir = tmpDir || fs.getTempFile();
|
|
||||||
|
|
||||||
const tmpDataDir = fs.join(instanceInfo.flatTmpDataDir, testname);
|
|
||||||
const appDir = fs.join(tmpDataDir, "apps");
|
|
||||||
|
|
||||||
fs.makeDirectoryRecursive(tmpDataDir);
|
|
||||||
instanceInfo.tmpDataDir = tmpDataDir;
|
|
||||||
|
|
||||||
// startup in cluster mode
|
|
||||||
let res = false;
|
|
||||||
|
|
||||||
if (options.cluster) {
|
|
||||||
res = startInstanceCluster(instanceInfo, protocol, options,
|
|
||||||
addArgs, testname, appDir, tmpDataDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
// agency testing mode
|
|
||||||
else if (options.agency) {
|
|
||||||
res = startInstanceAgency(instanceInfo, protocol, options,
|
|
||||||
addArgs, testname, appDir, tmpDataDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
// single instance mode
|
|
||||||
else {
|
|
||||||
res = startInstanceSingleServer(instanceInfo, protocol, options,
|
|
||||||
addArgs, testname, appDir, tmpDataDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!res) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait until the server/coordinator is up:
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
|
||||||
let url;
|
|
||||||
if (instanceInfo.endpoint !== undefined) {
|
|
||||||
url = endpointToURL(instanceInfo.endpoint);
|
|
||||||
instanceInfo.url = url;
|
|
||||||
} else {
|
|
||||||
instanceInfo.urls = instanceInfo.endpoints.map(endpointToURL);
|
|
||||||
url = instanceInfo.urls[instanceInfo.urls.length - 1];
|
|
||||||
instanceInfo.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
wait(0.5, false);
|
wait(0.5, false);
|
||||||
|
|
||||||
const reply = download(url + "/_api/version", "", makeAuthorizationHeaders(options));
|
const reply = download(instanceInfo.url + "/_api/version", "", makeAuthorizationHeaders(options));
|
||||||
|
|
||||||
if (!reply.error && reply.code === 200) {
|
if (!reply.error && reply.code === 200) {
|
||||||
break;
|
break;
|
||||||
|
@ -1797,21 +1314,17 @@ function startInstance(protocol, options, addArgs, testname, tmpDir) {
|
||||||
|
|
||||||
if (count % 60 === 0) {
|
if (count % 60 === 0) {
|
||||||
if (!checkInstanceAlive(instanceInfo, options)) {
|
if (!checkInstanceAlive(instanceInfo, options)) {
|
||||||
print("startup failed! bailing out!");
|
throw new Error("startup failed! bailing out!");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (platform.substr(0, 3) === 'win') {
|
||||||
print("up and running in " + (time() - startTime) + " seconds");
|
|
||||||
|
|
||||||
if (!options.cluster && (platform.substr(0, 3) === 'win')) {
|
|
||||||
const procdumpArgs = [
|
const procdumpArgs = [
|
||||||
'-accepteula',
|
'-accepteula',
|
||||||
'-e',
|
'-e',
|
||||||
'-ma',
|
'-ma',
|
||||||
instanceInfo.pid.pid,
|
instanceInfo.pid,
|
||||||
fs.join(tmpDataDir, 'core.dmp')
|
fs.join(rootDir, 'core.dmp')
|
||||||
];
|
];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -1821,6 +1334,76 @@ function startInstance(protocol, options, addArgs, testname, tmpDir) {
|
||||||
throw x;
|
throw x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
print("up and running in " + (time() - startTime) + " seconds");
|
||||||
|
return instanceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
function startInstanceAgency(instanceInfo, protocol, options,
|
||||||
|
addArgs, testname, rootDir) {
|
||||||
|
|
||||||
|
const N = options.agencySize;
|
||||||
|
const ports = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < N; i++) {
|
||||||
|
let instanceArgs = _.clone(addArgs);
|
||||||
|
instanceArgs["agency.id"] = String(i);
|
||||||
|
instanceArgs["agency.size"] = String(N);
|
||||||
|
|
||||||
|
if (i === N - 1) {
|
||||||
|
let l = [];
|
||||||
|
for (let j = 0; j < N; j++) {
|
||||||
|
instanceInfo.arangods.forEach(arangod => {
|
||||||
|
l.push("--agency.endpoint");
|
||||||
|
l.push(arangod.endpoint);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
l.push("--agency.notify");
|
||||||
|
l.push("true");
|
||||||
|
|
||||||
|
instanceArgs["flatCommands"] = l;
|
||||||
|
}
|
||||||
|
let dir = fs.join(rootDir, 'agency-' + i);
|
||||||
|
fs.makeDirectoryRecursive(dir);
|
||||||
|
|
||||||
|
instanceInfo.arangods.push(startArango(protocol, options, instanceArgs, testname, rootDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceInfo.endpoint = instanceInfo.arangods[instanceInfo.arangods.length - 1].endpoint;
|
||||||
|
instanceInfo.url = instanceInfo.arangods[instanceInfo.arangods.length - 1].url;
|
||||||
|
print("Agency Endpoint: " + instanceInfo.endpoint);
|
||||||
|
|
||||||
|
return instanceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
function startInstanceSingleServer(instanceInfo, protocol, options,
|
||||||
|
addArgs, testname, rootDir) {
|
||||||
|
|
||||||
|
instanceInfo.arangods.push(startArango(protocol, options, addArgs, testname, rootDir));
|
||||||
|
instanceInfo.endpoint = instanceInfo.arangods[instanceInfo.arangods.length - 1].endpoint;
|
||||||
|
instanceInfo.url = instanceInfo.arangods[instanceInfo.arangods.length - 1].url;
|
||||||
|
|
||||||
|
return instanceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
function startInstance(protocol, options, addArgs, testname, tmpDir) {
|
||||||
|
let rootDir = fs.join(tmpDir || fs.getTempFile(), testname);
|
||||||
|
let instanceInfo = {rootDir, arangods: []};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (options.cluster) {
|
||||||
|
startInstanceCluster(instanceInfo, protocol, options,
|
||||||
|
addArgs, testname, rootDir);
|
||||||
|
} else if (options.agency) {
|
||||||
|
startInstanceAgency(instanceInfo, protocol, options,
|
||||||
|
addArgs, testname, rootDir);
|
||||||
|
} else {
|
||||||
|
startInstanceSingleServer(instanceInfo, protocol, options,
|
||||||
|
addArgs, testname, rootDir);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e, e.stack);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return instanceInfo;
|
return instanceInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ function agencyTestSuite () {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var agencyServers = ARGUMENTS;
|
var agencyServers = ARGUMENTS;
|
||||||
|
console.log(Array.prototype.slice.call(ARGUMENTS));
|
||||||
var whoseTurn = 0; // used to do round robin on agencyServers
|
var whoseTurn = 0; // used to do round robin on agencyServers
|
||||||
|
|
||||||
var request = require("@arangodb/request");
|
var request = require("@arangodb/request");
|
||||||
|
|
|
@ -3298,29 +3298,21 @@ static void JS_ExecuteExternal(
|
||||||
static void JS_StatusExternal(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
static void JS_StatusExternal(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
||||||
v8::HandleScope scope(isolate);
|
v8::HandleScope scope(isolate);
|
||||||
v8::Handle<v8::String> pidname = TRI_V8_ASCII_STRING("pid");
|
|
||||||
|
|
||||||
// extract the arguments
|
// extract the arguments
|
||||||
if (args.Length() < 1 || args.Length() > 2 || !args[0]->IsObject()) {
|
if (args.Length() < 1 || args.Length() > 2) {
|
||||||
TRI_V8_THROW_EXCEPTION_USAGE(
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
||||||
"statusExternal(<external-identifier>[, <wait>])");
|
"statusExternal(<external-identifier>[, <wait>])");
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(args[0]);
|
|
||||||
|
|
||||||
if (!obj->Has(pidname)) {
|
|
||||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
|
|
||||||
"statusExternal: pid must be given");
|
|
||||||
}
|
|
||||||
|
|
||||||
TRI_external_id_t pid;
|
TRI_external_id_t pid;
|
||||||
memset(&pid, 0, sizeof(TRI_external_id_t));
|
memset(&pid, 0, sizeof(TRI_external_id_t));
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
pid._pid =
|
pid._pid =
|
||||||
static_cast<TRI_pid_t>(TRI_ObjectToUInt64(obj->Get(pidname), true));
|
static_cast<TRI_pid_t>(TRI_ObjectToUInt64(args[0], true));
|
||||||
#else
|
#else
|
||||||
pid._pid = static_cast<DWORD>(TRI_ObjectToUInt64(obj->Get(pidname), true));
|
pid._pid = static_cast<DWORD>(TRI_ObjectToUInt64(args[0], true));
|
||||||
#endif
|
#endif
|
||||||
bool wait = false;
|
bool wait = false;
|
||||||
if (args.Length() == 2) {
|
if (args.Length() == 2) {
|
||||||
|
|
Loading…
Reference in New Issue