events-backend: rename consumedBy -> notifiedSubscribers

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-09-13 09:29:15 +02:00
parent ab0afa9bac
commit f1fb54af5b
9 changed files with 33 additions and 24 deletions
@@ -159,7 +159,7 @@ export const spec = {
event: {
$ref: '#/components/schemas/Event',
},
consumedBy: {
notifiedSubscribers: {
type: 'array',
description:
'The IDs of subscriptions that have already received this event',
@@ -106,7 +106,7 @@ paths:
properties:
event:
$ref: '#/components/schemas/Event'
consumedBy:
notifiedSubscribers:
type: array
description: The IDs of subscriptions that have already received this event
items:
@@ -119,12 +119,15 @@ describe('eventsPlugin', () => {
publish(
topic: string,
payload: unknown,
options?: { consumedBy?: string[] },
options?: { notifiedSubscribers?: string[] },
) {
return request(this.backend.server)
.post('/api/events/bus/v1/events')
.set('authorization', mockCredentials.service.header())
.send({ event: { topic, payload }, consumedBy: options?.consumedBy });
.send({
event: { topic, payload },
notifiedSubscribers: options?.notifiedSubscribers,
});
}
readEvents(id: string) {
@@ -278,7 +281,7 @@ describe('eventsPlugin', () => {
'test',
{ for: 'tester-2' },
{
consumedBy: ['tester-1'],
notifiedSubscribers: ['tester-1'],
},
)
.expect(201);
@@ -287,7 +290,7 @@ describe('eventsPlugin', () => {
'test',
{ for: 'tester-1' },
{
consumedBy: ['tester-2'],
notifiedSubscribers: ['tester-2'],
},
)
.expect(201);
@@ -362,7 +365,11 @@ describe('eventsPlugin', () => {
await helper.subscribe('tester', ['test']).expect(201);
await helper
.publish('test', { for: 'tester-2' }, { consumedBy: ['tester'] })
.publish(
'test',
{ for: 'tester-2' },
{ notifiedSubscribers: ['tester'] },
)
.expect(204);
await backend.stop();
@@ -349,10 +349,10 @@ export class DatabaseEventBusStore implements EventBusStore {
async publish(options: {
params: EventParams;
consumedBy?: string[];
notifiedSubscribers?: string[];
}): Promise<{ eventId: string } | undefined> {
const topic = options.params.topic;
const consumedBy = options.consumedBy ?? [];
const notifiedSubscribers = options.notifiedSubscribers ?? [];
// This query inserts a new event into the database, but only if there are
// subscribers to the topic that have not already been notified
const result = await this.#db
@@ -378,12 +378,12 @@ export class DatabaseEventBusStore implements EventBusStore {
metadata: options.params.metadata,
}),
]),
this.#db.raw('?', [consumedBy]),
this.#db.raw('?', [notifiedSubscribers]),
)
// The rest of this query is to check whether there are any
// subscribers that have not been notified yet
.from(TABLE_SUBSCRIPTIONS)
.whereNotIn('id', consumedBy) // Skip notified subscribers
.whereNotIn('id', notifiedSubscribers) // Skip notified subscribers
.andWhere(this.#db.raw('? = ANY(topics)', [topic])) // Match topic
.having(this.#db.raw('count(*)'), '>', 0), // Check if there are any results
)
@@ -20,7 +20,9 @@ import { NotFoundError } from '@backstage/errors';
const MAX_BATCH_SIZE = 10;
export class MemoryEventBusStore implements EventBusStore {
#events = new Array<EventParams & { seq: number; consumedBy: Set<string> }>();
#events = new Array<
EventParams & { seq: number; notifiedSubscribers: Set<string> }
>();
#subscribers = new Map<
string,
{ id: string; seq: number; topics: Set<string> }
@@ -32,14 +34,14 @@ export class MemoryEventBusStore implements EventBusStore {
async publish(options: {
params: EventParams;
consumedBy: string[];
notifiedSubscribers: string[];
}): Promise<{ eventId: string } | undefined> {
const topic = options.params.topic;
const consumedBy = new Set(options.consumedBy);
const notifiedSubscribers = new Set(options.notifiedSubscribers);
let hasOtherSubscribers = false;
for (const sub of this.#subscribers.values()) {
if (sub.topics.has(topic) && !consumedBy.has(sub.id)) {
if (sub.topics.has(topic) && !notifiedSubscribers.has(sub.id)) {
hasOtherSubscribers = true;
break;
}
@@ -49,7 +51,7 @@ export class MemoryEventBusStore implements EventBusStore {
}
const nextSeq = this.#getMaxSeq() + 1;
this.#events.push({ ...options.params, consumedBy, seq: nextSeq });
this.#events.push({ ...options.params, notifiedSubscribers, seq: nextSeq });
for (const listener of this.#listeners) {
if (listener.topics.has(topic)) {
@@ -88,7 +90,7 @@ export class MemoryEventBusStore implements EventBusStore {
event =>
event.seq > sub.seq &&
sub.topics.has(event.topic) &&
!event.consumedBy.has(id),
!event.notifiedSubscribers.has(id),
)
.slice(0, MAX_BATCH_SIZE);
@@ -158,13 +158,13 @@ export async function createEventBusRouter(options: {
allow: ['service'],
});
const topic = req.body.event.topic;
const consumedBy = req.body.consumedBy;
const notifiedSubscribers = req.body.notifiedSubscribers;
const result = await store.publish({
params: {
topic,
eventPayload: req.body.event.payload,
} as EventParams,
consumedBy: req.body.consumedBy,
notifiedSubscribers: req.body.notifiedSubscribers,
});
if (result) {
logger.info(`Published event to '${topic}' with ID '${result.eventId}'`, {
@@ -172,8 +172,8 @@ export async function createEventBusRouter(options: {
});
res.status(201).end();
} else {
if (consumedBy) {
const notified = `'${consumedBy.join("', '")}'`;
if (notifiedSubscribers) {
const notified = `'${notifiedSubscribers.join("', '")}'`;
logger.info(
`Skipped publishing of event to '${topic}', subscribers have already been notified: ${notified}`,
{ subject: credentials.principal.subject },
@@ -19,7 +19,7 @@ import { EventParams } from '@backstage/plugin-events-node';
export type EventBusStore = {
publish(options: {
params: EventParams;
consumedBy?: string[];
notifiedSubscribers?: string[];
}): Promise<{ eventId: string } | undefined>;
upsertSubscription(subscriptionId: string, topics: string[]): Promise<void>;
@@ -127,7 +127,7 @@ class PluginEventsService implements EventsService {
{
body: {
event: { payload: params.eventPayload, topic: params.topic },
consumedBy: notifiedSubscribers,
notifiedSubscribers,
},
},
{ token },
@@ -24,5 +24,5 @@ export interface PostEventRequest {
/**
* The IDs of subscriptions that have already received this event
*/
consumedBy?: Array<string>;
notifiedSubscribers?: Array<string>;
}