about summary refs log tree commit diff stats
path: root/js/blotbotboot/node_modules/irc/lib/cycling_ping_timer.js
blob: 1466df60b0e9c3eede56a8afd00521c3f46f51c0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
'use strict';

var util = require('util');
var EventEmitter = require('events').EventEmitter;

/**
 * This class encapsulates the ping timeout functionality. When enough
 * silence (lack of server-sent activity) time passes, an object of this type
 * will emit a 'wantPing' event, indicating you should send a PING message
 * to the server in order to get some signs of life from it. If enough
 * time passes after that (i.e. server does not respond to PING), then
 * an object of this type will emit a 'pingTimeout' event.
 *
 * To start the gears turning, call start() on an instance of this class To
 * put it in the 'started' state.
 *
 * When server-side activity occurs, call notifyOfActivity() on the object.
 *
 * When a pingTimeout occurs, the object will go into the 'stopped' state.
 */
var ctr = 0;

function CyclingPingTimer(client) {
    var timerNumber = ctr++;
    var started = false;
    var self = this;

    // Only one of these two should be non-null at any given time.
    var loopingTimeout = null;
    var pingWaitTimeout = null;

    // conditionally log debug messages
    function debug(msg) {
        if (client.opt.debug) {
            console.error('CyclingPingTimer ' + timerNumber + ': ' + msg);
        }
    }

    // set up EventEmitter functionality
    EventEmitter.call(self);

    self.on('wantPing', function() {
        debug('server silent for too long, let\'s send a PING');
        pingWaitTimeout = setTimeout(function() {
            self.stop();
            debug('ping timeout!');
            self.emit('pingTimeout');
        }, client.opt.millisecondsBeforePingTimeout);
    });

    self.notifyOfActivity = function() {
        if (started) {
            self.stop();
            self.start();
        }
    };

    self.stop = function() {
        if (!started) {
            return;
        }
        started = false;

        clearTimeout(loopingTimeout);
        clearTimeout(pingWaitTimeout);

        loopingTimeout = null;
        pingWaitTimeout = null;
    };

    self.start = function() {
        if (started) {
            debug('can\'t start, not stopped!');
            return;
        }
        started = true;

        loopingTimeout = setTimeout(function() {
            loopingTimeout = null;
            self.emit('wantPing');
        }, client.opt.millisecondsOfSilenceBeforePingSent);
    };
}

util.inherits(CyclingPingTimer, EventEmitter);

module.exports = CyclingPingTimer;