В libuv вы можете в итоге связать рабочие потоки слишком большим количеством работы или ошибочным кодом. Существует ли простая функция, которая может проверять работоспособность рабочих потоков или очереди потоков? Он не должен быть на 100% детерминированным, в конце концов, было бы невозможно определить, зависает ли рабочий поток на медленном коде или бесконечном цикле.
Так что любая из следующих эвристик была бы хороша:
Количество объектов в очереди, над которыми еще не работали. Если он слишком велик, это может означать, что рабочие потоки заняты или зависают.
Есть ли в libuv какой-либо механизм уничтожения потоков, в котором, если рабочий поток не возвращается через n секунд, он прерывается?
Эта функция не существует в самой libuv, и я не знаю ни одной OSS, которая предоставляет что-то подобное.
С точки зрения механизма убийства, никто не запекается в libuv, но http://nikhilm.github.io/uvbook/threads.html#core-thread-operations предлагает:
У хорошо продуманной программы есть способ прекратить длительное выполнение
рабочие, которые уже начали казнить. Такой рабочий мог
периодически проверять переменную, которую устанавливает только основной процесс
прекращение сигнала.
Если это для nodejs, то подойдет ли простой поток мониторинга? Я не знаю, как получить информацию о внутренних объектах очереди событий, но вы можете внедрить трассировщик в очередь событий, чтобы следить за своевременным выполнением потоков. (Это измеряет нагрузку не по количеству потоков, которые еще не запущены, а по тому, выполняются ли потоки вовремя. То же самое, вроде.)
Поток монитора мог бы заново ставить в очередь и проверять, что он вызывается, по крайней мере, каждые 10 миллисекунд (или любое допустимое максимальное накопление мс). Так как nodej запускает потоки циклически, если поток монитора был запущен вовремя, он сообщает нам, что все остальные потоки получили возможность работать в том же окне 10 мс. Что-то вроде (в узле):
// like Date.now(), but with higher precision
// the extra precision is needed to be able to track small delays
function dateNow() {
var t = process.hrtime();
return (t[0] + t[1] * 1e-9) * 1000;
}
var _lastTimestamp = dateNow(); // when healthMonitor ran last, in ms
var _maxAllowedDelay = 10.0; // max ms delay we allow for our task to run
function healthMonitor() {
var now = dateNow();
var delay = now - _lastTimestamp;
if (delaly > _maxAllowedDelay) {
console.log("healthMonitor was late:", delay, " > ", _maxAllowedDelay);
}
_lastTimestamp = now;
setTimeout(healthMonitor, 1);
}
// launch the health monitor and run it forever
// note: the node process will never exit, it will have to be killed
healthMonitor();
Регулирование предупреждающих сообщений и поддержка полного отключения — это упражнение, оставленное читателю.