2025-02-05 11:21:22 +01:00
|
|
|
import type { PeerId } from "@libp2p/interface";
|
2025-07-11 12:55:02 +10:00
|
|
|
import { LightPushCore } from "@waku/core";
|
2024-03-11 18:50:34 +05:30
|
|
|
import {
|
2024-10-17 00:49:24 +02:00
|
|
|
type CoreProtocolResult,
|
2024-03-11 18:50:34 +05:30
|
|
|
Failure,
|
|
|
|
|
type IEncoder,
|
2024-10-04 10:50:58 +02:00
|
|
|
ILightPush,
|
2024-03-11 18:50:34 +05:30
|
|
|
type IMessage,
|
2025-02-25 22:40:03 +01:00
|
|
|
type ISendOptions,
|
2024-03-11 18:50:34 +05:30
|
|
|
type Libp2p,
|
2025-07-11 12:55:02 +10:00
|
|
|
type LightPushProtocolOptions,
|
2024-03-12 16:40:08 +05:30
|
|
|
ProtocolError,
|
2025-07-02 23:03:47 +02:00
|
|
|
Protocols,
|
2024-07-03 12:09:34 +05:30
|
|
|
SDKProtocolResult
|
2024-03-11 18:50:34 +05:30
|
|
|
} from "@waku/interfaces";
|
2025-02-25 22:40:03 +01:00
|
|
|
import { Logger } from "@waku/utils";
|
2024-03-11 18:50:34 +05:30
|
|
|
|
2025-01-31 00:16:00 +01:00
|
|
|
import { PeerManager } from "../peer_manager/index.js";
|
2024-03-11 18:50:34 +05:30
|
|
|
|
2025-02-25 22:40:03 +01:00
|
|
|
import { RetryManager } from "./retry_manager.js";
|
|
|
|
|
|
2024-03-11 18:50:34 +05:30
|
|
|
const log = new Logger("sdk:light-push");
|
|
|
|
|
|
2024-10-17 00:49:24 +02:00
|
|
|
const DEFAULT_MAX_ATTEMPTS = 3;
|
2025-02-25 22:40:03 +01:00
|
|
|
const DEFAULT_SEND_OPTIONS: LightPushProtocolOptions = {
|
|
|
|
|
autoRetry: true,
|
|
|
|
|
retryIntervalMs: 1000,
|
|
|
|
|
maxAttempts: DEFAULT_MAX_ATTEMPTS,
|
|
|
|
|
numPeersToUse: 1
|
2024-10-17 00:49:24 +02:00
|
|
|
};
|
|
|
|
|
|
2025-02-25 18:41:32 +01:00
|
|
|
type LightPushConstructorParams = {
|
|
|
|
|
peerManager: PeerManager;
|
|
|
|
|
libp2p: Libp2p;
|
2025-02-25 22:40:03 +01:00
|
|
|
options?: Partial<LightPushProtocolOptions>;
|
2025-02-25 18:41:32 +01:00
|
|
|
};
|
|
|
|
|
|
2024-10-17 00:49:24 +02:00
|
|
|
export class LightPush implements ILightPush {
|
2025-02-25 22:40:03 +01:00
|
|
|
private readonly config: LightPushProtocolOptions;
|
|
|
|
|
private readonly retryManager: RetryManager;
|
2025-06-20 12:53:42 +02:00
|
|
|
private readonly peerManager: PeerManager;
|
|
|
|
|
private readonly protocol: LightPushCore;
|
2024-09-17 11:34:59 +05:30
|
|
|
|
2025-02-25 18:41:32 +01:00
|
|
|
public constructor(params: LightPushConstructorParams) {
|
2025-02-25 22:40:03 +01:00
|
|
|
this.config = {
|
|
|
|
|
...DEFAULT_SEND_OPTIONS,
|
|
|
|
|
...(params.options || {})
|
|
|
|
|
} as LightPushProtocolOptions;
|
|
|
|
|
|
2025-02-25 18:41:32 +01:00
|
|
|
this.peerManager = params.peerManager;
|
feat!: re-architect connection manager (#2445)
* remove public pubsub field and redundant util
* add hangUp and improve dial operations, improve keepAliveManager and remove unused method, move utils and add tests
* improve public dial method to start keep alive checks
* move dial method
* implement discovery dialer
* implement discovery dialer with queue with tests
* add discovery dialer e2e tests, change local discovery log tag, update other tests
* remove comment
* add issue link, remove only
* implement shard reader component
* create evetns module, remove unused connection manager events and related tests
* implement network indicator
* implement connection limiter, change public API of connection manager, implement recovery strategy
* decouple keep alive maanger
* add connection manager js-doc
* refactor keep alive manager, cover with tests
* add tests for connection manager main facade
* add tests for connection limiter
* add e2e tests for connection manager modules
pass js-waku config during test node init
remove dns discovery for js-waku
* restructure dialing tests
* address last e2e tests
* address review
* add logging for main methods
* decouple pure dialer class, update network monitor with specific metrics
* remove console.log
* remove usage of protocols
* update sdk package tests
* add connect await promise
* add debug for e2e tests
* enable only packages tests
* use only one file
* revert debugging
* up interface for netwrok manager
* add logs
* add more logs
* add more logs
* add another logs
* remove .only
* remove log statements
* skip the test with follow up
2025-07-09 21:23:14 +02:00
|
|
|
this.protocol = new LightPushCore(params.libp2p);
|
2025-02-25 22:40:03 +01:00
|
|
|
this.retryManager = new RetryManager({
|
|
|
|
|
peerManager: params.peerManager,
|
|
|
|
|
retryIntervalMs: this.config.retryIntervalMs
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-20 12:53:42 +02:00
|
|
|
public get multicodec(): string {
|
|
|
|
|
return this.protocol.multicodec;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-25 22:40:03 +01:00
|
|
|
public start(): void {
|
|
|
|
|
this.retryManager.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public stop(): void {
|
|
|
|
|
this.retryManager.stop();
|
2024-03-11 18:50:34 +05:30
|
|
|
}
|
|
|
|
|
|
2024-07-19 15:58:17 +05:30
|
|
|
public async send(
|
2024-06-19 01:52:16 -04:00
|
|
|
encoder: IEncoder,
|
|
|
|
|
message: IMessage,
|
2025-02-25 22:40:03 +01:00
|
|
|
options: ISendOptions = {}
|
2024-06-19 01:52:16 -04:00
|
|
|
): Promise<SDKProtocolResult> {
|
2025-02-25 22:40:03 +01:00
|
|
|
options = {
|
|
|
|
|
...this.config,
|
|
|
|
|
...options
|
|
|
|
|
};
|
2024-03-11 18:50:34 +05:30
|
|
|
|
|
|
|
|
const { pubsubTopic } = encoder;
|
2025-02-25 22:40:03 +01:00
|
|
|
|
|
|
|
|
log.info("send: attempting to send a message to pubsubTopic:", pubsubTopic);
|
|
|
|
|
|
2025-07-02 23:03:47 +02:00
|
|
|
const peerIds = await this.peerManager.getPeers({
|
|
|
|
|
protocol: Protocols.LightPush,
|
|
|
|
|
pubsubTopic: encoder.pubsubTopic
|
|
|
|
|
});
|
2024-03-11 18:50:34 +05:30
|
|
|
|
2025-07-02 23:03:47 +02:00
|
|
|
const coreResults: CoreProtocolResult[] =
|
|
|
|
|
peerIds?.length > 0
|
|
|
|
|
? await Promise.all(
|
|
|
|
|
peerIds.map((peerId) =>
|
|
|
|
|
this.protocol.send(encoder, message, peerId).catch((_e) => ({
|
|
|
|
|
success: null,
|
|
|
|
|
failure: {
|
|
|
|
|
error: ProtocolError.GENERIC_FAIL
|
|
|
|
|
}
|
|
|
|
|
}))
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
: [];
|
|
|
|
|
|
|
|
|
|
const results: SDKProtocolResult = coreResults.length
|
|
|
|
|
? {
|
|
|
|
|
successes: coreResults
|
|
|
|
|
.filter((v) => v.success)
|
|
|
|
|
.map((v) => v.success) as PeerId[],
|
|
|
|
|
failures: coreResults
|
|
|
|
|
.filter((v) => v.failure)
|
|
|
|
|
.map((v) => v.failure) as Failure[]
|
|
|
|
|
}
|
|
|
|
|
: {
|
|
|
|
|
successes: [],
|
|
|
|
|
failures: [
|
|
|
|
|
{
|
|
|
|
|
error: ProtocolError.NO_PEER_AVAILABLE
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
2024-10-17 00:49:24 +02:00
|
|
|
|
2025-02-25 22:40:03 +01:00
|
|
|
if (options.autoRetry && results.successes.length === 0) {
|
|
|
|
|
const sendCallback = (peerId: PeerId): Promise<CoreProtocolResult> =>
|
|
|
|
|
this.protocol.send(encoder, message, peerId);
|
|
|
|
|
this.retryManager.push(
|
|
|
|
|
sendCallback.bind(this),
|
2025-07-02 23:03:47 +02:00
|
|
|
options.maxAttempts || DEFAULT_MAX_ATTEMPTS,
|
|
|
|
|
encoder.pubsubTopic
|
2024-10-17 00:49:24 +02:00
|
|
|
);
|
|
|
|
|
}
|
2025-02-25 22:40:03 +01:00
|
|
|
|
|
|
|
|
return results;
|
2024-10-17 00:49:24 +02:00
|
|
|
}
|
2024-03-11 18:50:34 +05:30
|
|
|
}
|