Skip to content

Commit b4c3e6a

Browse files
committed
Prevent addCOntextListener race conditions by making ChannelSupport a Connectable
1 parent c4e6bff commit b4c3e6a

6 files changed

Lines changed: 23 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6868
* Resolved vulnerable dependencies (esbuild, serialize-javascript, elliptic) and consolidated shared devDependencies to simplify future maintenance. ([#1841](https://github.com/finos/FDC3/pull/1841))
6969
* Fixed the lack of handling of WCP6Disconnect messages in MessagePort example in the FDC3 Web reference implementation. ([#1854](https://github.com/finos/FDC3/pull/1854))
7070
* Fixed handling of DesktopAgents that start apps joined to a user channel by the agent-proxy by retrieving the current user channel on start-up. ([#1858](https://github.com/finos/FDC3/pull/1858))
71+
* Fixed a race condition in `DefaultChannelSupport` initialization where the current user channel was retrieved asynchronously without being awaited, which could cause apps started on a user channel by the Desktop Agent to miss their initial channel assignment. ([#1858](https://github.com/finos/FDC3/pull/1858))
7172

7273
## [FDC3 Standard 2.2](https://github.com/finos/FDC3/compare/v2.1..v2.2) - 2025-03-12
7374

packages/fdc3-agent-proxy/src/channels/ChannelSupport.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1-
import { Channel, ContextHandler, EventHandler, FDC3EventTypes, Listener, PrivateChannel } from '@finos/fdc3-standard';
1+
import {
2+
Channel,
3+
Connectable,
4+
ContextHandler,
5+
EventHandler,
6+
FDC3EventTypes,
7+
Listener,
8+
PrivateChannel,
9+
} from '@finos/fdc3-standard';
210

3-
export interface ChannelSupport {
11+
export interface ChannelSupport extends Connectable {
412
getUserChannel(): Promise<Channel | null>;
513
getUserChannels(): Promise<Channel[]>;
614
getOrCreate(id: string): Promise<Channel>;

packages/fdc3-agent-proxy/src/channels/DefaultChannelSupport.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
Channel,
3+
Connectable,
34
ContextHandler,
45
Listener,
56
PrivateChannel,
@@ -35,7 +36,7 @@ import {
3536
import { throwIfUndefined } from '../util/throwIfUndefined.js';
3637
import { Logger } from '../util/Logger.js';
3738

38-
export class DefaultChannelSupport implements ChannelSupport {
39+
export class DefaultChannelSupport implements ChannelSupport, Connectable {
3940
readonly messaging: Messaging;
4041
readonly channelSelector: ChannelSelector;
4142
readonly messageExchangeTimeout: number;
@@ -55,14 +56,14 @@ export class DefaultChannelSupport implements ChannelSupport {
5556
this.joinUserChannel(channelId);
5657
}
5758
});
59+
}
5860

61+
async connect(): Promise<void> {
5962
//retrieve the current user channel in case the Desktop Agent started us on a channel
60-
this.getUserChannel().then((channel: Channel | null) => {
61-
this.currentChannel = channel;
62-
});
63+
this.currentChannel = await this.getUserChannel();
6364

6465
//register for channelChangedEvents to track any DesktopAgent managed user channel changes
65-
this.addEventListener(async (e: ApiEvent) => {
66+
await this.addEventListener(async (e: ApiEvent) => {
6667
const cce = e as FDC3ChannelChangedEvent;
6768
const newChannelId = cce.details.currentChannelId;
6869
Logger.debug('Desktop Agent reports channel changed: ', newChannelId);
@@ -91,6 +92,10 @@ export class DefaultChannelSupport implements ChannelSupport {
9192
}, 'userChannelChanged');
9293
}
9394

95+
async disconnect(): Promise<void> {
96+
// no-op
97+
}
98+
9499
async addEventListener(handler: EventHandler, type: FDC3EventTypes | null): Promise<Listener> {
95100
const listener = new DesktopAgentEventListener(this.messaging, this.messageExchangeTimeout, type, handler);
96101
await listener.register();

packages/fdc3-agent-proxy/test/features/user-channels-set-by-agent.feature

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ Feature: User Channels Support where the Desktop Agent puts the app on a channel
1313
Then "{result}" is an object with the following contents
1414
| id | type | displayMetadata.color |
1515
| one | user | red |
16-
And messaging will have posts
17-
| meta.source.appId | meta.source.instanceId | matches_type |
18-
| cucumber-app | cucumber-instance | getCurrentChannelRequest |
1916

2017
Scenario: Adding a Typed Listener on a given User Channel
2118
Given "resultHandler" pipes context to "contexts"

packages/fdc3-agent-proxy/test/step-definitions/generic.steps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function createDesktopAgent(world: CustomWorld, field: string, initialChannelId?
3131
const is = new DefaultIntentSupport(world.messaging, new SimpleIntentResolver(world), 1500, 3000);
3232
const as = new DefaultAppSupport(world.messaging, 1500, 3000);
3333

34-
const da = new DesktopAgentProxy(hs, cs, is, as, [hs], logLevel);
34+
const da = new DesktopAgentProxy(hs, cs, is, as, [hs, cs], logLevel);
3535
return da;
3636
}
3737

packages/fdc3-get-agent/src/messaging/message-port.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export async function createDesktopAgentAPI(
5454
const cs = new DefaultChannelSupport(messaging, channelSelector, cd.messageExchangeTimeout);
5555
const is = new DefaultIntentSupport(messaging, intentResolver, cd.messageExchangeTimeout, cd.appLaunchTimeout);
5656
const as = new DefaultAppSupport(messaging, cd.messageExchangeTimeout, cd.appLaunchTimeout);
57-
const da = new DesktopAgentProxy(hs, cs, is, as, [hs, intentResolver, channelSelector], logLevel);
57+
const da = new DesktopAgentProxy(hs, cs, is, as, [hs, cs, intentResolver, channelSelector], logLevel);
5858

5959
Logger.debug('message-port: Connecting components ...');
6060

0 commit comments

Comments
 (0)