Skip to content

Commit f62a66a

Browse files
committed
refactor: move single channelSubscriber as the first subscriber
Signed-off-by: Philippe Martin <[email protected]>
1 parent 2053b2c commit f62a66a

File tree

5 files changed

+53
-12
lines changed

5 files changed

+53
-12
lines changed

packages/extension/src/dashboard-extension.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import { PodLogsApiImpl } from './manager/pod-logs-api-impl';
4545
import { PodTerminalsApiImpl } from './manager/pod-terminals-api-impl';
4646
import { NavigationApiImpl } from '/@/manager/navigation-api';
4747
import { KubernetesProvidersManager } from '/@/manager/kubernetes-providers';
48+
import { ChannelSubscriber } from '/@/types/channel-subscriber';
4849

4950
export class DashboardExtension {
5051
#container: Container | undefined;
@@ -61,6 +62,7 @@ export class DashboardExtension {
6162
#podTerminalsApiImpl: PodTerminalsApiImpl;
6263
#navigationApiImpl: NavigationApiImpl;
6364
#kubernetesProvidersManager: KubernetesProvidersManager;
65+
#webviewSubscriber: ChannelSubscriber;
6466

6567
constructor(readonly extensionContext: ExtensionContext) {
6668
this.#extensionContext = extensionContext;
@@ -89,14 +91,15 @@ export class DashboardExtension {
8991
this.#podTerminalsApiImpl = await this.#container.getAsync(PodTerminalsApiImpl);
9092
this.#navigationApiImpl = await this.#container.getAsync(NavigationApiImpl);
9193
this.#kubernetesProvidersManager = await this.#container.getAsync(KubernetesProvidersManager);
94+
this.#webviewSubscriber = await this.#container.getAsync(ChannelSubscriber);
9295

9396
this.#kubernetesProvidersManager.init();
9497

9598
const afterFirst = performance.now();
9699

97100
console.log('activation time:', afterFirst - now);
98101

99-
rpcExtension.registerInstance(API_SUBSCRIBE, this.#contextsStatesDispatcher);
102+
rpcExtension.registerInstance(API_SUBSCRIBE, this.#webviewSubscriber);
100103
rpcExtension.registerInstance(API_CONTEXTS, this.#contextsManager);
101104
rpcExtension.registerInstance(API_SYSTEM, this.#systemApiImpl);
102105
rpcExtension.registerInstance(API_PORT_FORWARD, this.#portForwardApiImpl);

packages/extension/src/inject/inversify-binding.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { RpcExtension } from '@kubernetes-dashboard/rpc';
2626
import { managersModule } from '/@/manager/_manager-module';
2727
import { dispatchersModule } from '/@/dispatcher/_dispatcher-module';
2828
import { portForwardModule } from '/@/port-forward/_port-forward-module';
29+
import { typesModule } from '/@/types/_types_modules';
2930

3031
export class InversifyBinding {
3132
#container: Container | undefined;
@@ -56,6 +57,7 @@ export class InversifyBinding {
5657
await this.#container.load(managersModule);
5758
await this.#container.load(dispatchersModule);
5859
await this.#container.load(portForwardModule);
60+
await this.#container.load(typesModule);
5961

6062
return this.#container;
6163
}

packages/extension/src/manager/contexts-states-dispatcher.spec.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import {
4747
UPDATE_RESOURCE,
4848
} from '@kubernetes-dashboard/channels';
4949
import { KubernetesProvidersManager } from '/@/manager/kubernetes-providers.js';
50+
import { ChannelSubscriber } from '/@/types/channel-subscriber.js';
5051

5152
let container: Container;
5253
const contextsManagerMock: ContextsManager = {
@@ -86,7 +87,11 @@ const kubernetesProvidersManagerMock = {
8687
onKubernetesProvidersChange: vi.fn(),
8788
getKubernetesProviders: vi.fn(),
8889
} as unknown as KubernetesProvidersManager;
89-
90+
const webviewSubscriberMock = {
91+
onSubscribe: vi.fn(),
92+
hasSubscribers: vi.fn(),
93+
getSubscriptions: vi.fn(),
94+
} as unknown as ChannelSubscriber;
9095
beforeAll(async () => {
9196
const inversifyBinding = new InversifyBinding(rpcExtension, extensionContext, telemetryLogger);
9297
container = await inversifyBinding.initBindings();
@@ -96,6 +101,7 @@ beforeAll(async () => {
96101
(await container.rebind(ContextsHealthsDispatcher)).toConstantValue(contextsHealthsDispatcher);
97102
(await container.rebind(ContextsPermissionsDispatcher)).toConstantValue(contextsPermissionsDispatcher);
98103
(await container.rebind(KubernetesProvidersManager)).toConstantValue(kubernetesProvidersManagerMock);
104+
(await container.rebind(ChannelSubscriber)).toConstantValue(webviewSubscriberMock);
99105
});
100106

101107
beforeEach(() => {
@@ -206,9 +212,9 @@ test('ContextsStatesDispatcher should dispatch CURRENT_CONTEXT when onCurrentCon
206212
test('dispatchByChannelName is called when onSubscribe emits an event', async () => {
207213
const dispatchByChannelNameSpy = vi.spyOn(dispatcher, 'dispatchByChannelName').mockResolvedValue();
208214

209-
vi.spyOn(dispatcher, 'onSubscribe').mockImplementation(f => f('channel1') as IDisposable);
215+
vi.mocked(webviewSubscriberMock.onSubscribe).mockImplementation(f => f('channel1') as IDisposable);
210216
dispatcher.init();
211-
expect(dispatchByChannelNameSpy).toHaveBeenCalledWith('channel1');
217+
expect(dispatchByChannelNameSpy).toHaveBeenCalledWith(webviewSubscriberMock, 'channel1');
212218
});
213219

214220
test('ContextsStatesDispatcher should dispatch ENDPOINTS when onEndpointsChange event is fired', async () => {

packages/extension/src/manager/contexts-states-dispatcher.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import {
2929
RESOURCE_EVENTS,
3030
RESOURCES_COUNT,
3131
UPDATE_RESOURCE,
32-
SubscribeApi,
3332
KUBERNETES_PROVIDERS,
3433
} from '@kubernetes-dashboard/channels';
3534

@@ -45,7 +44,7 @@ import { PortForwardServiceProvider } from '/@/port-forward/port-forward-service
4544
import { KubernetesProvidersManager } from '/@/manager/kubernetes-providers.js';
4645

4746
@injectable()
48-
export class ContextsStatesDispatcher extends ChannelSubscriber implements SubscribeApi {
47+
export class ContextsStatesDispatcher {
4948
@inject(ContextsManager)
5049
private manager: ContextsManager;
5150

@@ -55,10 +54,12 @@ export class ContextsStatesDispatcher extends ChannelSubscriber implements Subsc
5554
@inject(KubernetesProvidersManager)
5655
private kubernetesProvidersManager: KubernetesProvidersManager;
5756

57+
@inject(ChannelSubscriber)
58+
private webviewSubscriber: ChannelSubscriber;
59+
5860
#dispatchers: Map<string, DispatcherObject<unknown>> = new Map();
5961

6062
constructor(@multiInject(DispatcherObject) dispatchers: DispatcherObject<unknown>[]) {
61-
super();
6263
dispatchers.forEach(dispatcher => {
6364
this.#dispatchers.set(dispatcher.channelName, dispatcher);
6465
});
@@ -103,10 +104,12 @@ export class ContextsStatesDispatcher extends ChannelSubscriber implements Subsc
103104
this.manager.onEndpointsChange(async () => {
104105
await this.dispatch(ENDPOINTS);
105106
});
106-
this.onSubscribe(channelName => this.dispatchByChannelName(channelName));
107107
this.kubernetesProvidersManager.onKubernetesProvidersChange(async () => {
108108
await this.dispatch(KUBERNETES_PROVIDERS);
109109
});
110+
111+
this.webviewSubscriber.onSubscribe(channelName => this.dispatchByChannelName(this.webviewSubscriber, channelName));
112+
// TODO onSubscribe on other subscribers
110113
}
111114

112115
// TODO replace this with an event
@@ -115,14 +118,15 @@ export class ContextsStatesDispatcher extends ChannelSubscriber implements Subsc
115118
}
116119

117120
async dispatch(channel: RpcChannel<unknown>): Promise<void> {
118-
return this.dispatchByChannelName(channel.name);
121+
return this.dispatchByChannelName(this.webviewSubscriber, channel.name);
122+
// TODO dispatch to other subscribers
119123
}
120124

121-
async dispatchByChannelName(channelName: string): Promise<void> {
122-
if (!this.hasSubscribers(channelName)) {
125+
async dispatchByChannelName(subscriber: ChannelSubscriber, channelName: string): Promise<void> {
126+
if (!subscriber.hasSubscribers(channelName)) {
123127
return;
124128
}
125-
const subscriptions = this.getSubscriptions(channelName);
129+
const subscriptions = subscriber.getSubscriptions(channelName);
126130

127131
const dispatcher = this.#dispatchers.get(channelName);
128132
if (!dispatcher) {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**********************************************************************
2+
* Copyright (C) 2025 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
19+
import { ContainerModule } from 'inversify';
20+
import { ChannelSubscriber } from '/@/types/channel-subscriber';
21+
22+
const typesModule = new ContainerModule(options => {
23+
options.bind<ChannelSubscriber>(ChannelSubscriber).toSelf().inSingletonScope();
24+
});
25+
26+
export { typesModule };

0 commit comments

Comments
 (0)