Skip to content

Commit 56d95d7

Browse files
authored
[ws-man-bridge] Publish ws-instance-update - WEB-592 (#18162)
* [ws-man-bridge] Publish ws-instance-update * tests * fix * fix
1 parent f25767b commit 56d95d7

File tree

7 files changed

+87
-7
lines changed

7 files changed

+87
-7
lines changed

components/gitpod-protocol/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ export * from "./context-url";
1717
export * from "./teams-projects-protocol";
1818
export * from "./snapshot-url";
1919
export * from "./webhook-event";
20+
export * from "./redis";
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copyright (c) 2023 Gitpod GmbH. All rights reserved.
3+
* Licensed under the GNU Affero General Public License (AGPL).
4+
* See License.AGPL.txt in the project root for license information.
5+
*/
6+
7+
export const WorkspaceInstanceUpdatesChannel = "chan:workspace-instances";
8+
9+
export type RedisWorkspaceInstanceUpdate = {
10+
instanceID: string;
11+
workspaceID: string;
12+
};

components/ws-manager-bridge/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"rimraf": "^3.0.2",
5353
"ts-node": "^10.4.0",
5454
"typescript": "~4.4.2",
55-
"watch": "^1.0.2"
55+
"watch": "^1.0.2",
56+
"ioredis-mock": "^8.7.0"
5657
}
5758
}

components/ws-manager-bridge/src/bridge.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,10 @@ export class WorkspaceManagerBridge implements Disposable {
364364
await lifecycleHandler();
365365
}
366366
await this.messagebus.notifyOnInstanceUpdate(ctx, userId, instance);
367-
await this.publisher.publishInstanceUpdate();
367+
await this.publisher.publishInstanceUpdate({
368+
instanceID: instance.id,
369+
workspaceID: instance.workspaceId,
370+
});
368371
} catch (e) {
369372
TraceContext.setError({ span }, e);
370373
throw e;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
* Licensed under the GNU Affero General Public License (AGPL).
4+
* See License.AGPL.txt in the project root for license information.
5+
*/
6+
7+
import { suite, test } from "@testdeck/mocha";
8+
import * as chai from "chai";
9+
import { RedisPublisher } from "./publisher";
10+
import { Metrics } from "../metrics";
11+
import { RedisClient } from "./client";
12+
import { Container, ContainerModule } from "inversify";
13+
14+
const expect = chai.expect;
15+
const Redis = require("ioredis-mock");
16+
17+
@suite
18+
class TestRedisPublisher {
19+
protected container: Container;
20+
21+
public before() {
22+
const client = {
23+
get: () => new Redis(),
24+
} as RedisClient;
25+
26+
this.container = new Container();
27+
this.container.load(
28+
new ContainerModule((bind) => {
29+
bind(Metrics).toSelf().inSingletonScope();
30+
bind(RedisClient).toConstantValue(client);
31+
bind(RedisPublisher).toSelf().inSingletonScope();
32+
}),
33+
);
34+
}
35+
36+
@test public publishInstanceUpdate() {
37+
const publisher = this.container.get(RedisPublisher);
38+
expect(() => {
39+
publisher.publishInstanceUpdate({
40+
instanceID: "123",
41+
workspaceID: "foo-bar-123",
42+
});
43+
}).not.to.throw;
44+
}
45+
}
46+
module.exports = new TestRedisPublisher();

components/ws-manager-bridge/src/redis/publisher.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,33 @@
77
import { inject, injectable } from "inversify";
88
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
99
import { Metrics } from "../metrics";
10+
import { RedisClient } from "./client";
11+
import { RedisWorkspaceInstanceUpdate, WorkspaceInstanceUpdatesChannel } from "@gitpod/gitpod-protocol";
1012

1113
@injectable()
1214
export class RedisPublisher {
13-
constructor(@inject(Metrics) private readonly metrics: Metrics) {}
15+
constructor(
16+
@inject(RedisClient) private readonly client: RedisClient,
17+
@inject(Metrics) private readonly metrics: Metrics,
18+
) {}
1419

1520
async publishPrebuildUpdate(): Promise<void> {
1621
log.debug("[redis] Publish prebuild udpate invoked.");
1722
this.metrics.reportUpdatePublished("prebuild");
1823
}
1924

20-
async publishInstanceUpdate(): Promise<void> {
21-
log.debug("[redis] Publish instance udpate invoked.");
22-
this.metrics.reportUpdatePublished("workspace-instance");
25+
async publishInstanceUpdate(update: RedisWorkspaceInstanceUpdate): Promise<void> {
26+
let err: Error | undefined;
27+
try {
28+
const serialized = JSON.stringify(update);
29+
await this.client.get().publish(WorkspaceInstanceUpdatesChannel, serialized);
30+
log.debug("[redis] Succesfully published instance update.", update);
31+
} catch (e) {
32+
err = e;
33+
log.error("[redis] Failed to publish instance update.", e, update);
34+
} finally {
35+
this.metrics.reportUpdatePublished("workspace-instance", err);
36+
}
2337
}
2438

2539
async publishHeadlessUpdate(): Promise<void> {

components/ws-manager-bridge/src/workspace-instance-controller.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,10 @@ export class WorkspaceInstanceControllerImpl implements WorkspaceInstanceControl
274274
await this.onStopped(ctx, info.workspace.ownerId, info.latestInstance);
275275

276276
await this.messagebus.notifyOnInstanceUpdate(ctx, info.workspace.ownerId, info.latestInstance);
277-
await this.publisher.publishInstanceUpdate();
277+
await this.publisher.publishInstanceUpdate({
278+
instanceID: info.latestInstance.id,
279+
workspaceID: info.workspace.id,
280+
});
278281

279282
await this.prebuildUpdater.stopPrebuildInstance(ctx, info.latestInstance);
280283
}

0 commit comments

Comments
 (0)