forked from CringeStudios/gamja
Implement exponential backoff for reconnections
Closes: https://todo.sr.ht/~emersion/gamja/118
This commit is contained in:
parent
ab3d4dd661
commit
f81c564d23
@ -25,7 +25,8 @@ const permanentCaps = [
|
|||||||
"soju.im/bouncer-networks",
|
"soju.im/bouncer-networks",
|
||||||
];
|
];
|
||||||
|
|
||||||
const RECONNECT_DELAY_SEC = 10;
|
const RECONNECT_MIN_DELAY_MSEC = 10 * 1000; // 10s
|
||||||
|
const RECONNECT_MAX_DELAY_MSEC = 10 * 60 * 1000; // 10min
|
||||||
|
|
||||||
// WebSocket status codes
|
// WebSocket status codes
|
||||||
// https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1
|
// https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1
|
||||||
@ -64,6 +65,38 @@ class IRCError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements a simple exponential backoff.
|
||||||
|
*/
|
||||||
|
class Backoff {
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
constructor(min, max) {
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.n = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
next() {
|
||||||
|
if (this.n === 0) {
|
||||||
|
this.n = 1;
|
||||||
|
return this.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
let dur = this.n * this.min;
|
||||||
|
if (dur > this.max) {
|
||||||
|
dur = this.max;
|
||||||
|
} else {
|
||||||
|
this.n *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default class Client extends EventTarget {
|
export default class Client extends EventTarget {
|
||||||
static Status = {
|
static Status = {
|
||||||
DISCONNECTED: "disconnected",
|
DISCONNECTED: "disconnected",
|
||||||
@ -95,6 +128,7 @@ export default class Client extends EventTarget {
|
|||||||
batches = new Map();
|
batches = new Map();
|
||||||
autoReconnect = true;
|
autoReconnect = true;
|
||||||
reconnectTimeoutID = null;
|
reconnectTimeoutID = null;
|
||||||
|
reconnectBackoff = new Backoff(RECONNECT_MIN_DELAY_MSEC, RECONNECT_MAX_DELAY_MSEC);
|
||||||
pingIntervalID = null;
|
pingIntervalID = null;
|
||||||
pendingCmds = {
|
pendingCmds = {
|
||||||
WHO: Promise.resolve(null),
|
WHO: Promise.resolve(null),
|
||||||
@ -171,11 +205,12 @@ export default class Client extends EventTarget {
|
|||||||
};
|
};
|
||||||
window.addEventListener("online", handleOnline);
|
window.addEventListener("online", handleOnline);
|
||||||
} else {
|
} else {
|
||||||
console.info("Reconnecting to server in " + RECONNECT_DELAY_SEC + " seconds");
|
let delay = this.reconnectBackoff.next();
|
||||||
|
console.info("Reconnecting to server in " + (delay / 1000) + " seconds");
|
||||||
clearTimeout(this.reconnectTimeoutID);
|
clearTimeout(this.reconnectTimeoutID);
|
||||||
this.reconnectTimeoutID = setTimeout(() => {
|
this.reconnectTimeoutID = setTimeout(() => {
|
||||||
this.reconnect();
|
this.reconnect();
|
||||||
}, RECONNECT_DELAY_SEC * 1000);
|
}, delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -210,6 +245,8 @@ export default class Client extends EventTarget {
|
|||||||
console.log("Connection opened");
|
console.log("Connection opened");
|
||||||
this.setStatus(Client.Status.REGISTERING);
|
this.setStatus(Client.Status.REGISTERING);
|
||||||
|
|
||||||
|
this.reconnectBackoff.reset();
|
||||||
|
|
||||||
this.nick = this.params.nick;
|
this.nick = this.params.nick;
|
||||||
|
|
||||||
this.send({ command: "CAP", params: ["LS", "302"] });
|
this.send({ command: "CAP", params: ["LS", "302"] });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user