<commit_before>/*
    On first heartbeat, add host to list.
    Periodically sweep to expire.
    On missing host, fire alert.

{
    name: 'heartbeat',
    ttl: 16000,
    host: 'example-1',
    time: 1401651649819
}

*/


var
    _       = require('lodash'),
    assert  = require('assert'),
    bole    = require('bole'),
    stream  = require('stream'),
    TTLPool = require('ttl-pool'),
    util    = require('util')
    ;

var WARN_THRESHOLD = 0;

var Heartbeat = module.exports = function Heartbeat()
{
    stream.Writable.call(this, { objectMode: true });

    this.pool = TTLPool(this.handleExpire.bind(this));
    this.hosts = {};
    this.log = bole('heartbeat');
};
util.inherits(Heartbeat, stream.Writable);

Heartbeat.prototype.pool = null;
Heartbeat.prototype.hosts = null;

Heartbeat.prototype._write = function _write(event, encoding, callback)
{
    switch (event.name)
    {
    case 'heartbeat':
        return this.handleHeartbeat(event, callback);

    case 'shutdown':
        return this.handleShutdown(event, callback);
    }

    callback();
};

Heartbeat.prototype.handleHeartbeat = function handleHeartbeat(event, callback)
{
    if (this.hosts[event.host])
    {
        this.pool.ping(event.host, event.ttl);
        this.hosts[event.host].skipped = 0;
    }
    else
    {
        this.log.info('now tracking heartbeats for ' + event.host);
        this.pool.add(event.host, event.ttl);
        this.hosts[event.host] = event;
        event.skipped = 0;
    }

    callback();<commit_msg>Make sure host is in the `TTLPool` before pinging it<commit_after>/*
    On first heartbeat, add host to list.
    Periodically sweep to expire.
    On missing host, fire alert.

{
    name: 'heartbeat',
    ttl: 16000,
    host: 'example-1',
    time: 1401651649819
}

*/


var
    _       = require('lodash'),
    assert  = require('assert'),
    bole    = require('bole'),
    stream  = require('stream'),
    TTLPool = require('ttl-pool'),
    util    = require('util')
    ;

var WARN_THRESHOLD = 0;

var Heartbeat = module.exports = function Heartbeat()
{
    stream.Writable.call(this, { objectMode: true });

    this.pool = TTLPool(this.handleExpire.bind(this));
    this.hosts = {};
    this.log = bole('heartbeat');
};
util.inherits(Heartbeat, stream.Writable);

Heartbeat.prototype.pool = null;
Heartbeat.prototype.hosts = null;

Heartbeat.prototype._write = function _write(event, encoding, callback)
{
    switch (event.name)
    {
    case 'heartbeat':
        return this.handleHeartbeat(event, callback);

    case 'shutdown':
        return this.handleShutdown(event, callback);
    }

    callback();
};

Heartbeat.prototype.handleHeartbeat = function handleHeartbeat(event, callback)
{
    // This one's fun.
    // If host skips a beat (for example, a temporary freeze), `TTLPool` will
    // remove it from its internal dictionary. That would be fine, if
    // `TTLPool#ping` implicitely added it back, but it doesn't. Thus, we
    // call both `TTLPool#ping` and `TTLPool#add` in order to make sure that
    // the entry is actually in there.
    this.pool.add(event.host, event.ttl);

    if (this.hosts[event.host])
    {
        this.pool.ping(event.host, event.ttl);
        this.hosts[event.host].skipped = 0;
    }
    else
    {
        this.log.info('now tracking heartbeats for ' + event.host);
        this.hosts[event.host] = event;
        event.skipped = 0;
    }

    callback();
{'fraction_non_alphanumeric': 0.13441955193482688, 'fraction_numerical': 0.012801862089031132, 'mean_word_length': 2.7863436123348015, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1513033', 'n_tokens_mistral': 1185, 'n_tokens_neox': 1107, 'n_words': 261}