Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add options to broadcast Peer info on seeing a new subscription #109

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ export interface PubsubPeerDiscoveryInit {
* If true, we will not broadcast our peer data
*/
listenOnly?: boolean

/**
* If true, we will broadcast our data when we see new peers on the peer discovery topic (default: false).
* listenOnly must not be set to false for this capability to be applied.
*/
broadcastOnSubscribe?: boolean

/**
* Randomized backoff in milliseconds to wait before broadcasting on seeing a new subscription (default: 0.1 * interval).
*/
backoffOnSubscribe?: number
}

export interface PubSubPeerDiscoveryComponents {
Expand All @@ -44,6 +55,8 @@ export class PubSubPeerDiscovery extends EventEmitter<PeerDiscoveryEvents> imple
private readonly interval: number
private readonly listenOnly: boolean
private readonly topics: string[]
private readonly broadcastOnSubscribe: boolean
private readonly backoffOnSubscribe: number
private intervalId?: ReturnType<typeof setInterval>
private readonly components: PubSubPeerDiscoveryComponents

Expand All @@ -53,12 +66,16 @@ export class PubSubPeerDiscovery extends EventEmitter<PeerDiscoveryEvents> imple
const {
interval,
topics,
listenOnly
listenOnly,
broadcastOnSubscribe,
backoffOnSubscribe,
} = init

this.components = components
this.interval = interval ?? 10000
this.listenOnly = listenOnly ?? false
this.broadcastOnSubscribe = broadcastOnSubscribe ?? false
this.backoffOnSubscribe = backoffOnSubscribe ?? this.interval * 0.1;

// Ensure we have topics
if (Array.isArray(topics) && topics.length > 0) {
Expand Down Expand Up @@ -112,6 +129,20 @@ export class PubSubPeerDiscovery extends EventEmitter<PeerDiscoveryEvents> imple
return
}

// Broadcast on Subscribe from other peers
if (this.broadcastOnSubscribe) {
pubsub.addEventListener('subscription-change', subChangeEvt => {
// Check if the PubSub peer cares about PubSub Peer Discovery
const discoverySubs = subChangeEvt.detail.subscriptions.filter(sub => this.topics.includes(sub.topic));

// The Peer is interested in PubSub Peer Discovery -> broadcast
if (discoverySubs.length > 0) {
const backoff = this.backoffOnSubscribe * Math.random()
setTimeout(() => { this._broadcast() }, backoff)
}
})
}

// Broadcast immediately, and then run on interval
this._broadcast()

Expand Down