feat: move all signal handling to backend plugin
Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This commit is contained in:
@@ -24,7 +24,7 @@ export class SignalClient implements SignalApi {
|
||||
static readonly DEFAULT_RECONNECT_TIMEOUT_MS: number;
|
||||
// (undocumented)
|
||||
subscribe(
|
||||
topic: string,
|
||||
channel: string,
|
||||
onMessage: (message: JsonObject) => void,
|
||||
): {
|
||||
unsubscribe: () => void;
|
||||
|
||||
@@ -19,7 +19,7 @@ import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
type Subscription = {
|
||||
topic: string;
|
||||
channel: string;
|
||||
callback: (message: JsonObject) => void;
|
||||
};
|
||||
|
||||
@@ -63,20 +63,23 @@ export class SignalClient implements SignalApi {
|
||||
) {}
|
||||
|
||||
subscribe(
|
||||
topic: string,
|
||||
channel: string,
|
||||
onMessage: (message: JsonObject) => void,
|
||||
): { unsubscribe: () => void } {
|
||||
const subscriptionId = uuid();
|
||||
const exists = [...this.subscriptions.values()].find(
|
||||
sub => sub.topic === topic,
|
||||
sub => sub.channel === channel,
|
||||
);
|
||||
this.subscriptions.set(subscriptionId, { topic, callback: onMessage });
|
||||
this.subscriptions.set(subscriptionId, {
|
||||
channel: channel,
|
||||
callback: onMessage,
|
||||
});
|
||||
|
||||
this.connect()
|
||||
.then(() => {
|
||||
// Do not subscribe twice to same topic even there is multiple callbacks
|
||||
// Do not subscribe twice to same channel even there is multiple callbacks
|
||||
if (!exists) {
|
||||
this.send({ action: 'subscribe', topic });
|
||||
this.send({ action: 'subscribe', channel });
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
@@ -90,12 +93,12 @@ export class SignalClient implements SignalApi {
|
||||
}
|
||||
this.subscriptions.delete(subscriptionId);
|
||||
const multipleExists = [...this.subscriptions.values()].find(
|
||||
s => s.topic === topic,
|
||||
s => s.channel === channel,
|
||||
);
|
||||
// If there are subscriptions still listening to this topic, do not
|
||||
// If there are subscriptions still listening to this channel, do not
|
||||
// unsubscribe from the server
|
||||
if (!multipleExists) {
|
||||
this.send({ action: 'unsubscribe', topic: sub.topic });
|
||||
this.send({ action: 'unsubscribe', channel: sub.channel });
|
||||
}
|
||||
|
||||
// If there are no subscriptions, close the connection
|
||||
@@ -176,9 +179,9 @@ export class SignalClient implements SignalApi {
|
||||
private handleMessage(data: MessageEvent) {
|
||||
try {
|
||||
const json = JSON.parse(data.data) as JsonObject;
|
||||
if (json.topic) {
|
||||
if (json.channel) {
|
||||
for (const sub of this.subscriptions.values()) {
|
||||
if (sub.topic === json.topic) {
|
||||
if (sub.channel === json.channel) {
|
||||
sub.callback(json.message as JsonObject);
|
||||
}
|
||||
}
|
||||
@@ -201,9 +204,9 @@ export class SignalClient implements SignalApi {
|
||||
this.ws = null;
|
||||
this.connect()
|
||||
.then(() => {
|
||||
// Resubscribe to existing topics in case we lost connection
|
||||
// Resubscribe to existing channels in case we lost connection
|
||||
for (const sub of this.subscriptions.values()) {
|
||||
this.send({ action: 'subscribe', topic: sub.topic });
|
||||
this.send({ action: 'subscribe', channel: sub.channel });
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
@@ -44,21 +44,21 @@ describe('SignalsClient', () => {
|
||||
it('should handle single subscription correctly', async () => {
|
||||
const messageMock = jest.fn();
|
||||
const client = SignalClient.create({ discoveryApi, identity });
|
||||
const { unsubscribe } = client.subscribe('topic', messageMock);
|
||||
const { unsubscribe } = client.subscribe('channel', messageMock);
|
||||
await server.connected;
|
||||
|
||||
await expect(server).toReceiveMessage({
|
||||
action: 'subscribe',
|
||||
topic: 'topic',
|
||||
channel: 'channel',
|
||||
});
|
||||
server.send({ topic: 'topic', message: { hello: 'world' } });
|
||||
server.send({ channel: 'channel', message: { hello: 'world' } });
|
||||
expect(messageMock).toHaveBeenCalledWith({ hello: 'world' });
|
||||
|
||||
await unsubscribe();
|
||||
|
||||
await expect(server).toReceiveMessage({
|
||||
action: 'unsubscribe',
|
||||
topic: 'topic',
|
||||
channel: 'channel',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -68,11 +68,11 @@ describe('SignalsClient', () => {
|
||||
const client1 = SignalClient.create({ discoveryApi, identity });
|
||||
const client2 = SignalClient.create({ discoveryApi, identity });
|
||||
const { unsubscribe: unsubscribe1 } = client1.subscribe(
|
||||
'topic',
|
||||
'channel',
|
||||
messageMock1,
|
||||
);
|
||||
const { unsubscribe: unsubscribe2 } = client2.subscribe(
|
||||
'topic',
|
||||
'channel',
|
||||
messageMock2,
|
||||
);
|
||||
|
||||
@@ -80,22 +80,22 @@ describe('SignalsClient', () => {
|
||||
|
||||
await expect(server).toReceiveMessage({
|
||||
action: 'subscribe',
|
||||
topic: 'topic',
|
||||
channel: 'channel',
|
||||
});
|
||||
server.send({ topic: 'topic', message: { hello: 'world' } });
|
||||
server.send({ channel: 'channel', message: { hello: 'world' } });
|
||||
expect(messageMock1).toHaveBeenCalledWith({ hello: 'world' });
|
||||
expect(messageMock2).toHaveBeenCalledWith({ hello: 'world' });
|
||||
|
||||
await unsubscribe1();
|
||||
await expect(server).not.toReceiveMessage({
|
||||
action: 'unsubscribe',
|
||||
topic: 'topic',
|
||||
channel: 'channel',
|
||||
});
|
||||
|
||||
await unsubscribe2();
|
||||
await expect(server).toReceiveMessage({
|
||||
action: 'unsubscribe',
|
||||
topic: 'topic',
|
||||
channel: 'channel',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -108,11 +108,11 @@ describe('SignalsClient', () => {
|
||||
connectTimeout: 100,
|
||||
});
|
||||
|
||||
client.subscribe('topic', messageMock);
|
||||
client.subscribe('channel', messageMock);
|
||||
await server.connected;
|
||||
await expect(server).toReceiveMessage({
|
||||
action: 'subscribe',
|
||||
topic: 'topic',
|
||||
channel: 'channel',
|
||||
});
|
||||
|
||||
await server.server.emit('error', null);
|
||||
@@ -120,7 +120,7 @@ describe('SignalsClient', () => {
|
||||
await new Promise(r => setTimeout(r, 50));
|
||||
await expect(server).toReceiveMessage({
|
||||
action: 'subscribe',
|
||||
topic: 'topic',
|
||||
channel: 'channel',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user