mirror of
https://github.com/Cameri/nostream.git
synced 2025-07-09 22:59:51 +02:00
feat: ignore dupe subscriptions
This commit is contained in:
@ -39,7 +39,7 @@ export class SubscribeMessageHandler implements IMessageHandler, IAbortable {
|
|||||||
const reason = this.canSubscribe(subscriptionId, filters)
|
const reason = this.canSubscribe(subscriptionId, filters)
|
||||||
if (reason) {
|
if (reason) {
|
||||||
debug('subscription %s with %o rejected: %s', subscriptionId, filters, reason)
|
debug('subscription %s with %o rejected: %s', subscriptionId, filters, reason)
|
||||||
this.webSocket.emit(WebSocketAdapterEvent.Message, createNoticeMessage(`Subscription request rejected: ${reason}`))
|
this.webSocket.emit(WebSocketAdapterEvent.Message, createNoticeMessage(`Subscription rejected: ${reason}`))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,12 +85,18 @@ export class SubscribeMessageHandler implements IMessageHandler, IAbortable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private canSubscribe(subscriptionId: SubscriptionId, filters: SubscriptionFilter[]): string | undefined {
|
private canSubscribe(subscriptionId: SubscriptionId, filters: SubscriptionFilter[]): string | undefined {
|
||||||
|
const subscriptions = this.webSocket.getSubscriptions()
|
||||||
|
const existingSubscription = subscriptions.get(subscriptionId)
|
||||||
|
|
||||||
|
if (existingSubscription?.length && equals(filters, existingSubscription)) {
|
||||||
|
return `Duplicate subscription ${subscriptionId}: Ignorning`
|
||||||
|
}
|
||||||
|
|
||||||
const maxSubscriptions = this.settings().limits.client.subscription.maxSubscriptions
|
const maxSubscriptions = this.settings().limits.client.subscription.maxSubscriptions
|
||||||
if (maxSubscriptions > 0) {
|
if (maxSubscriptions > 0
|
||||||
const subscriptions = this.webSocket.getSubscriptions()
|
&& !existingSubscription?.length && subscriptions.size + 1 > maxSubscriptions
|
||||||
if (!subscriptions.has(subscriptionId) && subscriptions.size + 1 > maxSubscriptions) {
|
) {
|
||||||
return `Too many subscriptions: Number of subscriptions must be less than or equal to ${maxSubscriptions}`
|
return `Too many subscriptions: Number of subscriptions must be less than or equal to ${maxSubscriptions}`
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxFilters = this.settings().limits.client.subscription.maxFilters
|
const maxFilters = this.settings().limits.client.subscription.maxFilters
|
||||||
|
@ -30,7 +30,7 @@ const toDbEvent = (event: Event) => ({
|
|||||||
describe('SubscribeMessageHandler', () => {
|
describe('SubscribeMessageHandler', () => {
|
||||||
const subscriptionId: SubscriptionId = 'subscriptionId'
|
const subscriptionId: SubscriptionId = 'subscriptionId'
|
||||||
let filters: SubscriptionFilter[]
|
let filters: SubscriptionFilter[]
|
||||||
let subscriptions: Map<SubscriptionId, Set<SubscriptionFilter>>
|
let subscriptions: Map<SubscriptionId, SubscriptionFilter[]>
|
||||||
let handler: IMessageHandler & IAbortable
|
let handler: IMessageHandler & IAbortable
|
||||||
let webSocket: IWebSocketAdapter
|
let webSocket: IWebSocketAdapter
|
||||||
let eventRepository: IEventRepository
|
let eventRepository: IEventRepository
|
||||||
@ -94,7 +94,7 @@ describe('SubscribeMessageHandler', () => {
|
|||||||
await handler.handleMessage(message)
|
await handler.handleMessage(message)
|
||||||
|
|
||||||
expect(webSocketOnMessageStub).to.have.been.calledOnceWithExactly(
|
expect(webSocketOnMessageStub).to.have.been.calledOnceWithExactly(
|
||||||
['NOTICE', 'Subscription request rejected: reason']
|
['NOTICE', 'Subscription rejected: reason']
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -273,7 +273,7 @@ describe('SubscribeMessageHandler', () => {
|
|||||||
expect((handler as any).canSubscribe(subscriptionId, filters)).to.be.undefined
|
expect((handler as any).canSubscribe(subscriptionId, filters)).to.be.undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns undefined if client is resubscribing', () => {
|
it('returns reason if client is sending a duplicate subscription', () => {
|
||||||
settingsFactory.returns({
|
settingsFactory.returns({
|
||||||
limits: {
|
limits: {
|
||||||
client: {
|
client: {
|
||||||
@ -283,9 +283,11 @@ describe('SubscribeMessageHandler', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
subscriptions.set(subscriptionId, new Set([{}]))
|
filters = [{ authors: ['aa'] }]
|
||||||
|
subscriptions.set(subscriptionId, filters)
|
||||||
|
|
||||||
expect((handler as any).canSubscribe(subscriptionId, filters)).to.be.undefined
|
expect((handler as any).canSubscribe(subscriptionId, filters))
|
||||||
|
.to.equal('Duplicate subscription subscriptionId: Ignorning')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns reason if client subscriptions exceed limits', () => {
|
it('returns reason if client subscriptions exceed limits', () => {
|
||||||
@ -298,7 +300,7 @@ describe('SubscribeMessageHandler', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
subscriptions.set('other-sub', new Set())
|
subscriptions.set('other-sub', [])
|
||||||
|
|
||||||
expect((handler as any).canSubscribe(subscriptionId, filters)).to.equal('Too many subscriptions: Number of subscriptions must be less than or equal to 1')
|
expect((handler as any).canSubscribe(subscriptionId, filters)).to.equal('Too many subscriptions: Number of subscriptions must be less than or equal to 1')
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user