Browse Source

Coroutinise ConnectionInstance.connect

Mainly to improve readability.
tags/0.7.1^2
Kegan Dougal 3 years ago
parent
commit
8d0b82a82c
2 changed files with 34 additions and 60 deletions
  1. +1
    -1
      .eslintrc
  2. +33
    -59
      lib/irc/ConnectionInstance.js

+ 1
- 1
.eslintrc View File

@@ -25,7 +25,7 @@
"no-alert": 2,
"no-caller": 2,
"no-cond-assign": 2,
"no-constant-condition": 2,
"no-constant-condition": 0,
"no-debugger": 2,
"no-dupe-args": 2,
"no-dupe-keys": 2,


+ 33
- 59
lib/irc/ConnectionInstance.js View File

@@ -292,12 +292,12 @@ ConnectionInstance.prototype._resetPingSendTimer = function() {
* @param {Function} onCreatedCallback Called with the client when created.
* @return {Promise} Resolves to an ConnectionInstance or rejects.
*/
ConnectionInstance.create = function(server, opts, onCreatedCallback) {
ConnectionInstance.create = Promise.coroutine(function*(server, opts, onCreatedCallback) {
if (!opts.nick || !server) {
throw new Error("Bad inputs. Nick: " + opts.nick);
}
onCreatedCallback = onCreatedCallback || function() {};
var connectionOpts = {
let connectionOpts = {
userName: opts.username,
realName: opts.realname,
password: opts.password,
@@ -317,32 +317,43 @@ ConnectionInstance.create = function(server, opts, onCreatedCallback) {
connectionOpts.secure = { ca: server.getCA() };
}

// TODO : coroutine this
var d = promiseutil.defer();
var returnClient = function(cli) {
d.resolve(cli);
};
var retryConnection = function(e) {
var nodeClient = new irc.Client(
// Returns: A promise which resolves to a ConnectionInstance
let retryConnection = () => {
let nodeClient = new irc.Client(
server.domain, opts.nick, connectionOpts
);
var inst = new ConnectionInstance(
let inst = new ConnectionInstance(
nodeClient, server.domain, opts.nick
);
onCreatedCallback(inst);
return inst.connect();
};

var connAttempts = 0;
var retryTimeMs = 0;
var BASE_RETRY_TIME_MS = 1000;
function retryForever() {
let retryFailed = function(err) {
if (err && err.message) {
log.error(`retryFailed after ${connAttempts} attempts (${err.message})`);
let connAttempts = 0;
let retryTimeMs = 0;
const BASE_RETRY_TIME_MS = 1000;
while (true) {
try {
if (server.getReconnectIntervalMs() > 0) {
// wait until scheduled
let cli = yield Scheduler.reschedule(
server, retryTimeMs, retryConnection, opts.nick
);
return cli;
}
connAttempts += 1;
let delay = BASE_RETRY_TIME_MS + retryTimeMs +
Math.round((connAttempts * 1000) * Math.random());

log.info(`Scheduling disabled for ${opts.nick} on ${server.domain}, `+
`retrying with delay ${delay}ms (attempts ${connAttempts})`);
let cli = yield retryConnection();
return cli;
}
catch (err) {
connAttempts += 1;
log.error(
`ConnectionInstance.connect failed after ${connAttempts} attempts (${err.message})`
);
if (err.message === "throttled") {
retryTimeMs += THROTTLE_WAIT_MS;
}
@@ -351,49 +362,12 @@ ConnectionInstance.create = function(server, opts, onCreatedCallback) {
`${opts.nick} is banned from ${server.domain}, ` +
`retrying in ${BANNED_TIME_MS}ms`
);

setTimeout(() => {
retryFailed(
new Error(`${opts.nick} was banned from ${server.domain}, retrying now`)
);
}, BANNED_TIME_MS);
return;
}

if (server.getReconnectIntervalMs() > 0) {
// wait until scheduled
Scheduler.reschedule(server, retryTimeMs, retryConnection, opts.nick).then(
returnClient,
retryFailed
);
}
else {
let delay = BASE_RETRY_TIME_MS + retryTimeMs +
Math.round((connAttempts * 1000) * Math.random());

log.info(`Scheduling disabled for ${opts.nick} on ${server.domain}, `+
`retrying with delay ${delay}ms (attempts ${connAttempts})`);
retryConnection().then(
returnClient,
(e) => {
setTimeout(
() => {
retryFailed(e);
}
, delay);
}
);
yield Promise.delay(BANNED_TIME_MS);
}

};

// Initially, pretend to have failed in order to start things off
retryFailed({});
}
}
retryForever();

return d.promise;
};
throw new Error("ConnectionInstance.create: failed to connect");
});


module.exports = ConnectionInstance;

Loading…
Cancel
Save