-
Notifications
You must be signed in to change notification settings - Fork 275
Expand file tree
/
Copy pathconnection.js
More file actions
127 lines (100 loc) · 3.51 KB
/
Copy pathconnection.js
File metadata and controls
127 lines (100 loc) · 3.51 KB
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"use strict";
var EventEmitter = require('events').EventEmitter
, net = require('net')
, Utils = require('./utils')
, util = require('util');
exports.IssueLog = IssueLog; // connection issue handling
function ping (host, port, timeout, callback) {
var socket = net.createConnection({ port: port, host: host }, function (err) {
callback(err);
socket.end();
});
socket.setTimeout(timeout);
socket.on('error', function (err) {
callback(err);
socket.end();
});
}
function IssueLog (args) {
this.config = args;
this.messages = [];
this.failed = false;
this.locked = false;
this.isScheduledToReconnect = false;
this.totalFailures = 0;
this.retry = 0;
this.totalReconnectsAttempted = 0;
this.totalReconnectsSuccess = 0;
Utils.merge(this, args);
EventEmitter.call(this);
}
util.inherits(IssueLog, EventEmitter);
var issues = IssueLog.prototype;
issues.log = function log (message) {
var issue = this;
this.failed = true;
this.messages.push(message || 'No message specified');
// All failures must occur within `failuresTimeout` ms from the initial
// failure in order for node to be disconnected or removed.
if (this.failures && this.failures == this.config.failures)
this.failuresResetId = setTimeout(issue.failuresReset.bind(issue), this.failuresTimeout);
if (this.failures && !this.locked) {
this.locked = true;
setTimeout(issue.attemptRetry.bind(issue), this.retry);
return this.emit('issue', this.details);
}
if (this.failuresResetId) clearTimeout(this.failuresResetId);
if (this.remove) return this.emit('remove', this.details);
if (!this.isScheduledToReconnect) {
this.isScheduledToReconnect = true;
setTimeout(issue.attemptReconnect.bind(issue), this.reconnect);
}
};
issues.failuresReset = function failuresReset() {
//this.failures = this.config.failures;
Utils.merge(this, JSON.parse(JSON.stringify(this.config)));
};
Object.defineProperty(issues, 'details', {
get: function getDetails () {
var res = {};
res.server = this.server;
res.tokens = this.tokens;
res.messages = this.messages;
if (this.failures) {
res.failures = this.failures;
res.totalFailures = this.totalFailures;
} else {
res.totalReconnectsAttempted = this.totalReconnectsAttempted;
res.totalReconnectsSuccess = this.totalReconnectsSuccess;
res.totalReconnectsFailed = this.totalReconnectsAttempted - this.totalReconnectsSuccess;
res.totalDownTime = (res.totalReconnectsFailed * this.reconnect) + (this.totalFailures * this.retry);
}
return res;
}
});
issues.attemptRetry = function attemptRetry () {
this.totalFailures++;
this.failures--;
this.failed = false;
this.locked = false;
};
issues.attemptReconnect = function attemptReconnect () {
var issue = this;
this.totalReconnectsAttempted++;
this.emit('reconnecting', this.details);
// Ping the server
ping(this.tokens[1], this.tokens[0] || 11211, this.config.maxTimeout || 100, function pingpong (err) {
// still no access to the server
if (err) {
issue.messages.push(err.message || 'No message specified');
return setTimeout(issue.attemptReconnect.bind(issue), issue.reconnect);
}
issue.emit('reconnected', issue.details);
issue.totalReconnectsSuccess++;
issue.messages.length = 0;
issue.failed = false;
issue.isScheduledToReconnect = false;
// we connected again, so we are going through the whole cycle again
Utils.merge(issue, JSON.parse(JSON.stringify(issue.config)));
});
};