【发布时间】:2018-06-26 09:03:42
【问题描述】:
我正在尝试从节点脚本启动 Windows 服务。该服务有挂起的坏习惯,有时需要重试才能成功启动。我有一个承诺,而循环设置(请随时提出更好的方法)。我遇到的问题是,每个循环sc.pollInterval 输出都会在控制台中写入重复的结果。下面是我在控制台中看到的重复内容的示例,这是在循环的第二次迭代之后,我希望它只显示该内容一次。
sc \\abnf34873 start ColdFusion 10 Application Server
sc \\abnf34873 queryex ColdFusion 10 Application Server
SERVICE_NAME: ColdFusion 10 Application Server
TYPE : 10 WIN32_OWN_PROCESS
STATE : 2 START_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x7d0
PID : 0
FLAGS :
SERVICE_NAME: ColdFusion 10 Application Server
TYPE : 10 WIN32_OWN_PROCESS
STATE : 2 START_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x7d0
PID : 13772
FLAGS :
这是我的代码。基本上,我将尝试启动服务 3 次。如果没有,那么我会抛出错误。需要注意的一件事是,当我尝试启动服务但它停留在“Start_pending”状态时,我终止了该进程,然后尝试再次启动它。
var retryCount = 0;
// Start the colfusion service
gulp.task('start-coldfusion-service', function(done) {
var serviceStarted = false;
console.log("Starting coldfusion service..");
// This says we're going to ask where it's at every 30 seconds until it's in the desired state.
sc.pollInterval(30);
sc.timeout(60);
retryCount = 0;
tryServiceStart().then(function(result) {
// process final result here
done();
}).catch(function(err) {
// process error here
});
});
function tryServiceStart() {
return startService().then(function(serviceStarted) {
if (serviceStarted == false) {
console.log("Retry Count: " + retryCount);
// Try again..
return tryServiceStart();
} else {
return result;
}
});
}
function startService() {
return new Promise(function(resolve, reject) {
var started = true;
// Make sure the coldfusion service exists on the target server
sc.query(targetServer, { name: 'ColdFusion 10 Application Server'}).done(function(services) {
// if the service exists and it is currentl stopped, then we're going to start it.
if (services.length == 1) {
var pid = services[0].pid;
if (services[0].state.name == 'STOPPED') {
sc.start(targetServer, 'ColdFusion 10 Application Server')
.catch(function(error) {
started = false;
console.log("Problem starting Coldfusion service! error message: " + error.message);
console.log("retrying...");
retryCount++;
if (parseInt(retryCount) > 2) {
throw Error(error.message);
}
})
.done(function(displayName) {
if (started) {
console.log('Coldfusion service started successfully!');
}
resolve(started);
});
} else if (services[0].state.name == 'START_PENDING') {
kill(pid, {force: true}).catch(function (err) {
console.log('Problem killing process..');
}).then(function() {
console.log('Killed hanging process..');
resolve(false);
});
}
} else {
console.log("Could not find the service in a stopped state.");
resolve(false);
}
});
});
}
【问题讨论】:
-
service-control-manager 包声称“所有命令都返回一个承诺”,但是文档(您的代码正确遵守)告诉我们这些所谓的承诺具有
.done()和.catch()方法。尚不清楚.done()是否具有正确的.then()的全部功能,或者.done()是否只是像jQuery 的.done()那样的蹩脚的东西。这些例子表明后者,我没有在网上找到任何告诉我的东西。 -
感谢@Roamer-1888 提供的信息。我相信你是对的,因为它类似于 JQuery 的
.done()方法,因为它内部的任何内容每次都会执行,无论承诺被拒绝还是解决。无论如何,我找到了一个我很高兴使用 Promise-retry 包的解决方案。我会尽快发布新代码作为答案。 -
Jmh2013,我今天早些时候玩了一些想法。当我回到我的桌面时,我会将它们作为答案发布。
标签: javascript node.js promise gulp service-control-manager