*Add connection retry with backoff support

This commit is contained in:
Derrick Hammer 2023-02-16 21:47:49 -05:00
parent 524d647f21
commit db894376eb
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
2 changed files with 47 additions and 5 deletions

View File

@ -6,11 +6,13 @@
"dependencies": { "dependencies": {
"@lumeweb/libkernel-universal": "git+https://git.lumeweb.com/LumeWeb/libkernel-universal.git", "@lumeweb/libkernel-universal": "git+https://git.lumeweb.com/LumeWeb/libkernel-universal.git",
"@siaweb/libweb": "git+https://git.lumeweb.com/LumeWeb/libsiaweb.git", "@siaweb/libweb": "git+https://git.lumeweb.com/LumeWeb/libsiaweb.git",
"backoff": "^2.5.0",
"eventemitter3": "^5.0.0" "eventemitter3": "^5.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^18.11.19", "@types/backoff": "^2.5.2",
"prettier": "^2.8.3", "@types/node": "^18.13.0",
"prettier": "^2.8.4",
"pretty": "^2.0.0", "pretty": "^2.0.0",
"typescript": "^4.9.5" "typescript": "^4.9.5"
} }

View File

@ -4,13 +4,25 @@ import { hexToBuf, DataFn, ErrTuple } from "@siaweb/libweb";
import type { EventEmitter } from "eventemitter3"; import type { EventEmitter } from "eventemitter3";
import backoff, { Backoff } from "backoff";
export class SwarmClient extends Client { export class SwarmClient extends Client {
private useDefaultSwarm: boolean; private useDefaultSwarm: boolean;
private id: number = 0; private id: number = 0;
private _autoReconnect: boolean;
private _connectBackoff: Backoff;
constructor(useDefaultDht = true) { private _ready?: Promise<void>;
constructor(useDefaultDht = true, autoReconnect = false) {
super(); super();
this.useDefaultSwarm = useDefaultDht; this.useDefaultSwarm = useDefaultDht;
this._autoReconnect = autoReconnect;
this._connectBackoff = backoff.fibonacci();
this._connectBackoff.on("ready", () => {
this.start();
});
} }
get swarm(): number | undefined { get swarm(): number | undefined {
@ -31,10 +43,19 @@ export class SwarmClient extends Client {
return createSocket(resp.id); return createSocket(resp.id);
} }
async init(): Promise<ErrTuple> { async init(): Promise<ErrTuple> {
return this.callModuleReturn("init", { swarm: this.swarm }); const ret = await this.callModuleReturn("init", { swarm: this.swarm });
this._connectBackoff.reset();
return ret;
} }
async ready(): Promise<void> { async ready(): Promise<void> {
await this.callModuleReturn("ready", { swarm: this.swarm }); if (this._ready) {
return this._ready;
}
this._ready = this.callModuleReturn("ready", { swarm: this.swarm });
await this._ready;
this.connectModule( this.connectModule(
"listenConnections", "listenConnections",
@ -43,6 +64,25 @@ export class SwarmClient extends Client {
this.emit("connection", await createSocket(socketId)); this.emit("connection", await createSocket(socketId));
} }
); );
this._ready = undefined;
}
async start(): Promise<void> {
let ready = this.ready();
const backoff = () => setImmediate(() => this._connectBackoff.backoff());
try {
await this.init();
} catch (e) {
this.logErr(e);
backoff();
}
this.once("close", backoff);
await ready;
} }
public async addRelay(pubkey: string): Promise<void> { public async addRelay(pubkey: string): Promise<void> {