Node forever 说程序是 运行,但证据表明不是
Node forever says program is running, but evidence suggests not
我正在尝试 运行 使用 twit library and forever 的简单 twitterbot。该机器人本质上是在监视另一个推特帐户,并复制其推文并进行一些修改。
我一直在记录从流式传输 API 收到的推文,并记录所有错误。
然而,bot 经常会停止工作,同时记录没有错误,而 forever list
仍然显示程序为 运行ning。
info: Forever processes running
data: uid command script forever pid id logfile uptime
data: [0] QOmt /usr/bin/nodejs bot.js 13642 13649 /home/ubuntu/.forever/QOmt.log 0:5:25:34.733
起初,我认为这可能是 Twitter 流媒体的问题 API - 即信息已停止发送 "down the pipe",因为日志文件已停止记录来自推特流 API.
为了验证机器人确实还在 运行ning,我创建了一个 heartbeat
每分钟记录一次。
// Heartbeat to make sure the process is still running
setInterval(function () {
console.logWithDate('Program heartbeat');
}, 60*1000);
当机器人停止运行时,心跳也会停止记录。然而 forever
仍然说机器人是 运行ning。
非常感谢任何帮助。我 post 下面是我的机器人的完整代码,以防有用。
#!/usr/bin/env node
"use strict"
const fs = require('fs');
const util = require('util');
const Twit = require('twit');
// Logging
const error_log_file = fs.createWriteStream(__dirname + '/debug.log', {flags : 'a'});
const log_stdout = process.stdout;
console.error = function(d) {
error_log_file.write(util.format("\n%s> %s", new Date(), d) + '\n');
log_stdout.write(util.format("\n%s> %s", new Date(), d) + '\n');
};
console.logWithDate = function(d) {
log_stdout.write(util.format("\n%s> %s", new Date(), d) + '\n');
}
// Heartbeat to make sure the process is still running
setInterval(function () {
console.logWithDate('Program heartbeat');
}, 60*1000);
// Read in twitter secrets file
const twitter_secrets = JSON.parse(fs.readFileSync("twitter_secrets.json"));
// Connect to twitter
const client = new Twit({
consumer_key: twitter_secrets.TWITTER_CONSUMER_KEY,
consumer_secret: twitter_secrets.TWITTER_CONSUMER_SECRET,
access_token: twitter_secrets.TWITTER_ACCESS_TOKEN_KEY,
access_token_secret: twitter_secrets.TWITTER_ACCESS_TOKEN_SECRET,
timeouts_ms: 60*1000
});
// Main
const stream = client.stream('statuses/filter', {follow: 87818409});
stream.on('tweet', function(event) {
if (event.user.id === 87818409) {
console.logWithDate("Guardian tweet: " + event.text)
client.post(
'statuses/update',
{status: misspellRandomWords(event.text)},
function(error, tweet, response) {
if (error) {
console.error(error);
} else {
console.logWithDate("Bot tweet: " + tweet.text); // Tweet body.
//console.log(response); // Raw response object.
}
}
);
} else {
console.logWithDate("Guardian-related tweet: " + event.text)
}
});
// Log various types of messages for debugging
stream.on('limit', function(error) {
console.error(error);
});
stream.on('disconnect', function(error) {
console.error(error);
});
stream.on('error', function(error) {
console.error(error);
});
stream.on('connect', function (conn) {
console.logWithDate('connecting')
})
stream.on('reconnect', function (reconn, res, interval) {
console.logWithDate('reconnecting. statusCode:', res.statusCode)
})
/* Helper functions */
function swapRandomLetters(word) {
const limit = word.length;
const iFirstLetter = Math.floor(Math.random() * limit);
var iSecondLetter = Math.floor(Math.random() * limit);
while (iFirstLetter === iSecondLetter) {
iSecondLetter = Math.floor(Math.random() * limit);
}
let letters = word.split("");
letters[iFirstLetter] = word[iSecondLetter];
letters[iSecondLetter] = word[iFirstLetter];
return letters.join("");
}
function isLink(word) {
// Very crude URL check
return word.substring(0,4) === "http";
}
function misspellRandomWords(sentence) {
let words = sentence.split(" ");
const limit = words.length;
// Choose a first word, filtering out urls
var iFirstWord = Math.floor(Math.random() * limit);
while (isLink(words[iFirstWord]) || words[iFirstWord][0] === "@" ) {
iFirstWord = Math.floor(Math.random() * limit);
}
// Choose second misspelled word, and make sure it isn't the first or an URL
var iSecondWord = Math.floor(Math.random() * limit);
while (isLink(words[iSecondWord]) ||
iSecondWord === iFirstWord ||
words[iSecondWord][0] === "@") {
iSecondWord = Math.floor(Math.random() * limit);
}
words[iFirstWord] = swapRandomLetters(words[iFirstWord]);
words[iSecondWord] = swapRandomLetters(words[iSecondWord]);
return words.join(" ");
}
如果一条推文的所有单词都以 @
开头,就会出现死循环,从而阻塞主线程。
我正在尝试 运行 使用 twit library and forever 的简单 twitterbot。该机器人本质上是在监视另一个推特帐户,并复制其推文并进行一些修改。
我一直在记录从流式传输 API 收到的推文,并记录所有错误。
然而,bot 经常会停止工作,同时记录没有错误,而 forever list
仍然显示程序为 运行ning。
info: Forever processes running
data: uid command script forever pid id logfile uptime
data: [0] QOmt /usr/bin/nodejs bot.js 13642 13649 /home/ubuntu/.forever/QOmt.log 0:5:25:34.733
起初,我认为这可能是 Twitter 流媒体的问题 API - 即信息已停止发送 "down the pipe",因为日志文件已停止记录来自推特流 API.
为了验证机器人确实还在 运行ning,我创建了一个 heartbeat
每分钟记录一次。
// Heartbeat to make sure the process is still running
setInterval(function () {
console.logWithDate('Program heartbeat');
}, 60*1000);
当机器人停止运行时,心跳也会停止记录。然而 forever
仍然说机器人是 运行ning。
非常感谢任何帮助。我 post 下面是我的机器人的完整代码,以防有用。
#!/usr/bin/env node
"use strict"
const fs = require('fs');
const util = require('util');
const Twit = require('twit');
// Logging
const error_log_file = fs.createWriteStream(__dirname + '/debug.log', {flags : 'a'});
const log_stdout = process.stdout;
console.error = function(d) {
error_log_file.write(util.format("\n%s> %s", new Date(), d) + '\n');
log_stdout.write(util.format("\n%s> %s", new Date(), d) + '\n');
};
console.logWithDate = function(d) {
log_stdout.write(util.format("\n%s> %s", new Date(), d) + '\n');
}
// Heartbeat to make sure the process is still running
setInterval(function () {
console.logWithDate('Program heartbeat');
}, 60*1000);
// Read in twitter secrets file
const twitter_secrets = JSON.parse(fs.readFileSync("twitter_secrets.json"));
// Connect to twitter
const client = new Twit({
consumer_key: twitter_secrets.TWITTER_CONSUMER_KEY,
consumer_secret: twitter_secrets.TWITTER_CONSUMER_SECRET,
access_token: twitter_secrets.TWITTER_ACCESS_TOKEN_KEY,
access_token_secret: twitter_secrets.TWITTER_ACCESS_TOKEN_SECRET,
timeouts_ms: 60*1000
});
// Main
const stream = client.stream('statuses/filter', {follow: 87818409});
stream.on('tweet', function(event) {
if (event.user.id === 87818409) {
console.logWithDate("Guardian tweet: " + event.text)
client.post(
'statuses/update',
{status: misspellRandomWords(event.text)},
function(error, tweet, response) {
if (error) {
console.error(error);
} else {
console.logWithDate("Bot tweet: " + tweet.text); // Tweet body.
//console.log(response); // Raw response object.
}
}
);
} else {
console.logWithDate("Guardian-related tweet: " + event.text)
}
});
// Log various types of messages for debugging
stream.on('limit', function(error) {
console.error(error);
});
stream.on('disconnect', function(error) {
console.error(error);
});
stream.on('error', function(error) {
console.error(error);
});
stream.on('connect', function (conn) {
console.logWithDate('connecting')
})
stream.on('reconnect', function (reconn, res, interval) {
console.logWithDate('reconnecting. statusCode:', res.statusCode)
})
/* Helper functions */
function swapRandomLetters(word) {
const limit = word.length;
const iFirstLetter = Math.floor(Math.random() * limit);
var iSecondLetter = Math.floor(Math.random() * limit);
while (iFirstLetter === iSecondLetter) {
iSecondLetter = Math.floor(Math.random() * limit);
}
let letters = word.split("");
letters[iFirstLetter] = word[iSecondLetter];
letters[iSecondLetter] = word[iFirstLetter];
return letters.join("");
}
function isLink(word) {
// Very crude URL check
return word.substring(0,4) === "http";
}
function misspellRandomWords(sentence) {
let words = sentence.split(" ");
const limit = words.length;
// Choose a first word, filtering out urls
var iFirstWord = Math.floor(Math.random() * limit);
while (isLink(words[iFirstWord]) || words[iFirstWord][0] === "@" ) {
iFirstWord = Math.floor(Math.random() * limit);
}
// Choose second misspelled word, and make sure it isn't the first or an URL
var iSecondWord = Math.floor(Math.random() * limit);
while (isLink(words[iSecondWord]) ||
iSecondWord === iFirstWord ||
words[iSecondWord][0] === "@") {
iSecondWord = Math.floor(Math.random() * limit);
}
words[iFirstWord] = swapRandomLetters(words[iFirstWord]);
words[iSecondWord] = swapRandomLetters(words[iSecondWord]);
return words.join(" ");
}
如果一条推文的所有单词都以 @
开头,就会出现死循环,从而阻塞主线程。