fix: connection race

This commit is contained in:
2024-04-25 13:50:24 +01:00
parent 5af182c1bd
commit 38af05edb8
2 changed files with 14 additions and 6 deletions

View File

@ -21,7 +21,7 @@ export interface ConnectionTypeEvents {
unknownMessage: (obj: Array<any>) => void; unknownMessage: (obj: Array<any>) => void;
} }
export interface ConnectionSubscription {} export interface ConnectionSubscription { }
/** /**
* Basic relay connection * Basic relay connection
@ -93,15 +93,14 @@ export type ConnectionBuilder<T extends ConnectionType> = (
address: string, address: string,
options: RelaySettings, options: RelaySettings,
ephemeral: boolean, ephemeral: boolean,
) => Promise<T>; ) => Promise<T> | T;
/** /**
* Simple connection pool containing connections to multiple nostr relays * Simple connection pool containing connections to multiple nostr relays
*/ */
export class DefaultConnectionPool<T extends ConnectionType = Connection> export class DefaultConnectionPool<T extends ConnectionType = Connection>
extends EventEmitter<ConnectionPoolEvents> extends EventEmitter<ConnectionPoolEvents>
implements ConnectionPool implements ConnectionPool {
{
#system: SystemInterface; #system: SystemInterface;
#log = debug("ConnectionPool"); #log = debug("ConnectionPool");
@ -122,7 +121,7 @@ export class DefaultConnectionPool<T extends ConnectionType = Connection>
this.#connectionBuilder = builder; this.#connectionBuilder = builder;
} else { } else {
this.#connectionBuilder = (addr, options, ephemeral) => { this.#connectionBuilder = (addr, options, ephemeral) => {
return Promise.resolve<T>(new Connection(addr, options, ephemeral) as unknown as T); return new Connection(addr, options, ephemeral) as unknown as T;
}; };
} }
} }

View File

@ -43,6 +43,7 @@ export class Connection extends EventEmitter<ConnectionTypeEvents> implements Co
#closing = false; #closing = false;
#downCount = 0; #downCount = 0;
#activeRequests = new Set<string>(); #activeRequests = new Set<string>();
#connectStarted = false;
id: string; id: string;
readonly address: string; readonly address: string;
@ -85,6 +86,10 @@ export class Connection extends EventEmitter<ConnectionTypeEvents> implements Co
return this.Socket?.readyState === WebSocket.OPEN; return this.Socket?.readyState === WebSocket.OPEN;
} }
get isConnecting() {
return this.Socket?.readyState === WebSocket.CONNECTING;
}
get isDown() { get isDown() {
return this.#downCount > 0; return this.#downCount > 0;
} }
@ -95,9 +100,12 @@ export class Connection extends EventEmitter<ConnectionTypeEvents> implements Co
async connect() { async connect() {
// already connected // already connected
if (this.isOpen) return; if (this.isOpen || this.isConnecting) return;
// wait for re-connect timer // wait for re-connect timer
if (this.ReconnectTimer) return; if (this.ReconnectTimer) return;
// prevent race condition
if (this.#connectStarted) return;
this.#connectStarted = true;
try { try {
if (this.info === undefined) { if (this.info === undefined) {
@ -138,6 +146,7 @@ export class Connection extends EventEmitter<ConnectionTypeEvents> implements Co
this.Socket.onmessage = e => this.#onMessage(e); this.Socket.onmessage = e => this.#onMessage(e);
this.Socket.onerror = e => this.#onError(e); this.Socket.onerror = e => this.#onError(e);
this.Socket.onclose = e => this.#onClose(e); this.Socket.onclose = e => this.#onClose(e);
this.#connectStarted = false;
} }
close() { close() {