Skip to content

Commit 5fa574a

Browse files
WillieHabiCopilot
andauthored
feat(container-extensions): true connection status for read and write clients (#24981)
## Description Fixes [AB#17920](https://dev.azure.com/fluidframework/235294da-091d-4c29-84fc-cdfc3d90890b/_workitems/edit/17920) Currently, `isConnected` for container extensions tells us when the local client is able to send ops. This is does not represent the true connection state for read clients, since they can be connected to service while still unable to send ops. This definiton of 'connected' is too restrictive for a signal-based container extension like Presence, since read clients should be considered 'connected' when they are able to send signals. To fix this, we pass container connection state to runtime to circumevent the lie in `Container.setContextConnectedState`, and for container extensions we replace`isConnected` with `getJoinedStatus` which can either be "joinedForReading", "joinedForWriting", or "disconnected". This way container extensions such as Presence are able to know when there is an active connection to service even in readonly mode. --------- Co-authored-by: Copilot <[email protected]>
1 parent a21c066 commit 5fa574a

24 files changed

+969
-153
lines changed

packages/common/container-definitions/api-report/container-definitions.beta.api.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@ export enum AttachState {
1313

1414
// @public
1515
export namespace ConnectionState {
16-
export type CatchingUp = 1;
17-
export type Connected = 2;
18-
export type Disconnected = 0;
19-
export type EstablishingConnection = 3;
16+
const Disconnected = 0;
17+
export type CatchingUp = typeof CatchingUp;
18+
const EstablishingConnection = 3;
19+
export type Connected = typeof Connected;
20+
const CatchingUp = 1;
21+
export type Disconnected = typeof Disconnected;
22+
const Connected = 2;
23+
export type EstablishingConnection = typeof EstablishingConnection;
2024
}
2125

2226
// @public

packages/common/container-definitions/api-report/container-definitions.legacy.alpha.api.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@ export enum AttachState {
1313

1414
// @public
1515
export namespace ConnectionState {
16-
export type CatchingUp = 1;
17-
export type Connected = 2;
18-
export type Disconnected = 0;
19-
export type EstablishingConnection = 3;
16+
const Disconnected = 0;
17+
export type CatchingUp = typeof CatchingUp;
18+
const EstablishingConnection = 3;
19+
export type Connected = typeof Connected;
20+
const CatchingUp = 1;
21+
export type Disconnected = typeof Disconnected;
22+
const Connected = 2;
23+
export type EstablishingConnection = typeof EstablishingConnection;
2024
}
2125

2226
// @public
@@ -140,6 +144,7 @@ export interface IContainerContext {
140144
// (undocumented)
141145
readonly disposeFn?: (error?: ICriticalContainerError) => void;
142146
getAbsoluteUrl?(relativeUrl: string): Promise<string | undefined>;
147+
readonly getConnectionState?: () => ConnectionState;
143148
// (undocumented)
144149
getLoadedFromVersion(): IVersion | undefined;
145150
// @deprecated

packages/common/container-definitions/api-report/container-definitions.legacy.public.api.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@ export enum AttachState {
1313

1414
// @public
1515
export namespace ConnectionState {
16-
export type CatchingUp = 1;
17-
export type Connected = 2;
18-
export type Disconnected = 0;
19-
export type EstablishingConnection = 3;
16+
const Disconnected = 0;
17+
export type CatchingUp = typeof CatchingUp;
18+
const EstablishingConnection = 3;
19+
export type Connected = typeof Connected;
20+
const CatchingUp = 1;
21+
export type Disconnected = typeof Disconnected;
22+
const Connected = 2;
23+
export type EstablishingConnection = typeof EstablishingConnection;
2024
}
2125

2226
// @public

packages/common/container-definitions/api-report/container-definitions.public.api.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@ export enum AttachState {
1313

1414
// @public
1515
export namespace ConnectionState {
16-
export type CatchingUp = 1;
17-
export type Connected = 2;
18-
export type Disconnected = 0;
19-
export type EstablishingConnection = 3;
16+
const Disconnected = 0;
17+
export type CatchingUp = typeof CatchingUp;
18+
const EstablishingConnection = 3;
19+
export type Connected = typeof Connected;
20+
const CatchingUp = 1;
21+
export type Disconnected = typeof Disconnected;
22+
const Connected = 2;
23+
export type EstablishingConnection = typeof EstablishingConnection;
2024
}
2125

2226
// @public

packages/common/container-definitions/src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ export { isIDeltaManagerFull } from "./deltas.js";
2929
export type { ContainerWarning, ICriticalContainerError } from "./error.js";
3030
export { ContainerErrorTypes } from "./error.js";
3131
export type {
32-
ConnectionState,
3332
ICodeDetailsLoader,
3433
IContainer,
3534
IContainerEvents,
@@ -45,7 +44,7 @@ export type {
4544
IResolvedFluidCodeDetails,
4645
ISnapshotTreeWithBlobContents,
4746
} from "./loader.js";
48-
export { LoaderHeader } from "./loader.js";
47+
export { ConnectionState, LoaderHeader } from "./loader.js";
4948
export type { IFluidModule } from "./fluidModule.js";
5049
export type {
5150
IFluidPackage,

packages/common/container-definitions/src/loader.ts

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -283,26 +283,42 @@ export namespace ConnectionState {
283283
* or may remain disconnected until explicitly told to connect.
284284
* @public
285285
*/
286-
export type Disconnected = 0;
286+
export const Disconnected = 0;
287+
/**
288+
* {@inheritdoc @fluidframework/container-definitions#(ConnectionState:namespace).(Disconnected:variable)}
289+
*/
290+
export type Disconnected = typeof Disconnected;
287291

288292
/**
289293
* The container is disconnected but actively trying to establish a new connection.
290294
* PLEASE NOTE that this numerical value falls out of the order you may expect for this state.
291295
* @public
292296
*/
293-
export type EstablishingConnection = 3;
297+
export const EstablishingConnection = 3;
298+
/**
299+
* {@inheritdoc @fluidframework/container-definitions#(ConnectionState:namespace).(EstablishingConnection:variable)}
300+
*/
301+
export type EstablishingConnection = typeof EstablishingConnection;
294302

295303
/**
296304
* The container has an inbound connection only, and is catching up to the latest known state from the service.
297305
* @public
298306
*/
299-
export type CatchingUp = 1;
307+
export const CatchingUp = 1;
308+
/**
309+
* {@inheritdoc @fluidframework/container-definitions#(ConnectionState:namespace).(CatchingUp:variable)}
310+
*/
311+
export type CatchingUp = typeof CatchingUp;
300312

301313
/**
302314
* The container is fully connected and syncing.
303315
* @public
304316
*/
305-
export type Connected = 2;
317+
export const Connected = 2;
318+
/**
319+
* {@inheritdoc @fluidframework/container-definitions#(ConnectionState:namespace).(Connected:variable)}
320+
*/
321+
export type Connected = typeof Connected;
306322
}
307323

308324
/**
@@ -462,7 +478,7 @@ export interface IContainer extends IEventProvider<IContainerEvents> {
462478
*
463479
* @remarks
464480
*
465-
* {@link IContainer.connectionState} will be set to {@link (ConnectionState:namespace).Connected}, and the
481+
* {@link IContainer.connectionState} will be set to {@link (ConnectionState:namespace).(Connected:variable)}, and the
466482
* "connected" event will be fired if/when connection succeeds.
467483
*/
468484
connect(): void;
@@ -472,7 +488,7 @@ export interface IContainer extends IEventProvider<IContainerEvents> {
472488
*
473489
* @remarks
474490
*
475-
* {@link IContainer.connectionState} will be set to {@link (ConnectionState:namespace).Disconnected}, and the
491+
* {@link IContainer.connectionState} will be set to {@link (ConnectionState:namespace).(Disconnected:variable)}, and the
476492
* "disconnected" event will be fired when disconnection completes.
477493
*/
478494
disconnect(): void;
@@ -485,7 +501,7 @@ export interface IContainer extends IEventProvider<IContainerEvents> {
485501
/**
486502
* The server provided ID of the client.
487503
*
488-
* Set once {@link IContainer.connectionState} is {@link (ConnectionState:namespace).Connected},
504+
* Set once {@link IContainer.connectionState} is {@link (ConnectionState:namespace).(Connected:variable)},
489505
* otherwise will be `undefined`.
490506
*/
491507
readonly clientId?: string | undefined;

packages/common/container-definitions/src/runtime.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import type {
3232
import type { IAudience } from "./audience.js";
3333
import type { IDeltaManager } from "./deltas.js";
3434
import type { ICriticalContainerError } from "./error.js";
35-
import type { ILoader } from "./loader.js";
35+
import type { ConnectionState, ILoader } from "./loader.js";
3636

3737
/**
3838
* The attachment state of some Fluid data (e.g. a container or data store), denoting whether it is uploaded to the
@@ -272,6 +272,15 @@ export interface IContainerContext {
272272
readonly storage: IContainerStorageService;
273273
readonly connected: boolean;
274274
readonly baseSnapshot: ISnapshotTree | undefined;
275+
276+
/**
277+
* Gets the current connection state of the container.
278+
*
279+
* @remarks
280+
* This provides more detailed connection state information beyond the simple boolean `connected` property.
281+
* Available starting from version 2.52.0. Property is not present in older versions.
282+
*/
283+
readonly getConnectionState?: () => ConnectionState;
275284
/**
276285
* @deprecated Please use submitBatchFn & submitSummaryFn
277286
*/

packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,14 @@ export enum ConnectionState {
140140

141141
// @public
142142
export namespace ConnectionStateType {
143-
export type CatchingUp = 1;
144-
export type Connected = 2;
145-
export type Disconnected = 0;
146-
export type EstablishingConnection = 3;
143+
const Disconnected = 0;
144+
export type CatchingUp = typeof CatchingUp;
145+
const EstablishingConnection = 3;
146+
export type Connected = typeof Connected;
147+
const CatchingUp = 1;
148+
export type Disconnected = typeof Disconnected;
149+
const Connected = 2;
150+
export type EstablishingConnection = typeof EstablishingConnection;
147151
}
148152

149153
// @public

packages/framework/fluid-framework/api-report/fluid-framework.beta.api.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,14 @@ export enum ConnectionState {
6060

6161
// @public
6262
export namespace ConnectionStateType {
63-
export type CatchingUp = 1;
64-
export type Connected = 2;
65-
export type Disconnected = 0;
66-
export type EstablishingConnection = 3;
63+
const Disconnected = 0;
64+
export type CatchingUp = typeof CatchingUp;
65+
const EstablishingConnection = 3;
66+
export type Connected = typeof Connected;
67+
const CatchingUp = 1;
68+
export type Disconnected = typeof Disconnected;
69+
const Connected = 2;
70+
export type EstablishingConnection = typeof EstablishingConnection;
6771
}
6872

6973
// @public

packages/framework/fluid-framework/api-report/fluid-framework.legacy.alpha.api.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,14 @@ export enum ConnectionState {
4949

5050
// @public
5151
export namespace ConnectionStateType {
52-
export type CatchingUp = 1;
53-
export type Connected = 2;
54-
export type Disconnected = 0;
55-
export type EstablishingConnection = 3;
52+
const Disconnected = 0;
53+
export type CatchingUp = typeof CatchingUp;
54+
const EstablishingConnection = 3;
55+
export type Connected = typeof Connected;
56+
const CatchingUp = 1;
57+
export type Disconnected = typeof Disconnected;
58+
const Connected = 2;
59+
export type EstablishingConnection = typeof EstablishingConnection;
5660
}
5761

5862
// @public

0 commit comments

Comments
 (0)