Skip to content

Commit 5721d4a

Browse files
authored
feat(client): processing during CatchingUp ConnectionState (#25750)
`IRuntime` now has an optional (preferred) `setConnectionStatus` method that replaces the previous `setConnectionState` method (still required for compatibility). The new method is called for all `ConnectionState` changes, including `CatchingUp` and `EstablishingConnection`. Calls may also be made when readonly state changes, even if there is no overall change in connection status. `ContainerRuntime` announces fewer "disconnected" events when a client is not fully connected and the readonly state changes. And add case to test missing setConnectionStatus while making its presence the default. Add internal Signal only based Audience that can be used while CatchingUp. For Container Extensions: - rename "connectionTypeChanged" event to "operabilityChanged" to allow for later move to operate during CatchingUp - Document JoinedStatus states
1 parent b5f65c6 commit 5721d4a

File tree

12 files changed

+527
-66
lines changed

12 files changed

+527
-66
lines changed

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,52 @@ export namespace ConnectionState {
2626
// @public
2727
export type ConnectionState = ConnectionState.Disconnected | ConnectionState.EstablishingConnection | ConnectionState.CatchingUp | ConnectionState.Connected;
2828

29+
// @beta @sealed @legacy
30+
export type ConnectionStatus = ConnectionStatusEstablishingConnection | ConnectionStatusCatchingUp | ConnectionStatusConnected | ConnectionStatusDisconnected;
31+
32+
// @beta @sealed @legacy
33+
export interface ConnectionStatusCatchingUp extends ConnectionStatusTemplate {
34+
// (undocumented)
35+
canSendOps: false;
36+
// (undocumented)
37+
connectionState: ConnectionState.CatchingUp;
38+
pendingClientConnectionId: string;
39+
}
40+
41+
// @beta @sealed @legacy
42+
export interface ConnectionStatusConnected extends ConnectionStatusTemplate {
43+
// (undocumented)
44+
canSendOps: boolean;
45+
clientConnectionId: string;
46+
// (undocumented)
47+
connectionState: ConnectionState.Connected;
48+
}
49+
50+
// @beta @sealed @legacy
51+
export interface ConnectionStatusDisconnected extends ConnectionStatusTemplate {
52+
// (undocumented)
53+
canSendOps: false;
54+
// (undocumented)
55+
connectionState: ConnectionState.Disconnected;
56+
priorConnectedClientConnectionId: string | undefined;
57+
priorPendingClientConnectionId: string | undefined;
58+
}
59+
60+
// @beta @sealed @legacy
61+
export interface ConnectionStatusEstablishingConnection extends ConnectionStatusTemplate {
62+
// (undocumented)
63+
canSendOps: false;
64+
// (undocumented)
65+
connectionState: ConnectionState.EstablishingConnection;
66+
}
67+
68+
// @beta @sealed @legacy
69+
export interface ConnectionStatusTemplate {
70+
canSendOps: boolean;
71+
// (undocumented)
72+
connectionState: ConnectionState;
73+
}
74+
2975
// @beta @legacy
3076
export const ContainerErrorTypes: {
3177
readonly clientSessionExpiredError: "clientSessionExpiredError";
@@ -157,6 +203,8 @@ export interface IContainerContext {
157203
// (undocumented)
158204
readonly quorum: IQuorumClients;
159205
readonly scope: FluidObject;
206+
// @system
207+
readonly signalAudience?: IAudience;
160208
readonly snapshotWithContents?: ISnapshot;
161209
// (undocumented)
162210
readonly storage: IContainerStorageService;
@@ -421,6 +469,7 @@ export interface IRuntime extends IDisposable {
421469
processSignal(message: any, local: boolean): any;
422470
setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void;
423471
setConnectionState(canSendOps: boolean, clientId?: string): any;
472+
setConnectionStatus?(status: ConnectionStatus): void;
424473
}
425474

426475
// @beta @legacy (undocumented)

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ export {
5959
isFluidCodeDetails,
6060
} from "./fluidPackage.js";
6161
export type {
62+
ConnectionStatus,
63+
ConnectionStatusCatchingUp,
64+
ConnectionStatusConnected,
65+
ConnectionStatusDisconnected,
66+
ConnectionStatusEstablishingConnection,
67+
ConnectionStatusTemplate,
6268
IBatchMessage,
6369
IContainerContext,
6470
IProvideRuntimeFactory,

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

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,92 @@ export enum AttachState {
5757
Attached = "Attached",
5858
}
5959

60+
/**
61+
* Defines the connection status of the container.
62+
*
63+
* @legacy @beta
64+
* @sealed
65+
*/
66+
export interface ConnectionStatusTemplate {
67+
connectionState: ConnectionState;
68+
/**
69+
* True if the runtime is currently allowed to send ops.
70+
*/
71+
canSendOps: boolean;
72+
}
73+
74+
/**
75+
* Status for an establishing connection.
76+
*
77+
* @legacy @beta
78+
* @sealed
79+
*/
80+
export interface ConnectionStatusEstablishingConnection extends ConnectionStatusTemplate {
81+
connectionState: ConnectionState.EstablishingConnection;
82+
canSendOps: false;
83+
}
84+
85+
/**
86+
* Status for an in-progress connection that is catching up to latest op state.
87+
*
88+
* @legacy @beta
89+
* @sealed
90+
*/
91+
export interface ConnectionStatusCatchingUp extends ConnectionStatusTemplate {
92+
connectionState: ConnectionState.CatchingUp;
93+
/**
94+
* The ID of the client connection that is connecting.
95+
*/
96+
pendingClientConnectionId: string;
97+
canSendOps: false;
98+
}
99+
100+
/**
101+
* Status for a full connection.
102+
*
103+
* @legacy @beta
104+
* @sealed
105+
*/
106+
export interface ConnectionStatusConnected extends ConnectionStatusTemplate {
107+
connectionState: ConnectionState.Connected;
108+
/**
109+
* The ID of the client connection that is connected.
110+
*/
111+
clientConnectionId: string;
112+
canSendOps: boolean;
113+
}
114+
115+
/**
116+
* Status for a disconnected connection.
117+
*
118+
* @legacy @beta
119+
* @sealed
120+
*/
121+
export interface ConnectionStatusDisconnected extends ConnectionStatusTemplate {
122+
connectionState: ConnectionState.Disconnected;
123+
canSendOps: false;
124+
/**
125+
* The ID of the client connection that was most recently connecting (catching up).
126+
*/
127+
priorPendingClientConnectionId: string | undefined;
128+
/**
129+
* The ID of the client connection that was most recently connected.
130+
*/
131+
priorConnectedClientConnectionId: string | undefined;
132+
}
133+
134+
/**
135+
* Connection status of the container.
136+
*
137+
* @legacy @beta
138+
* @sealed
139+
*/
140+
export type ConnectionStatus =
141+
| ConnectionStatusEstablishingConnection
142+
| ConnectionStatusCatchingUp
143+
| ConnectionStatusConnected
144+
| ConnectionStatusDisconnected;
145+
60146
/**
61147
* The IRuntime represents an instantiation of a code package within a Container.
62148
* Primarily held by the ContainerContext to be able to interact with the running instance of the Container.
@@ -68,9 +154,24 @@ export interface IRuntime extends IDisposable {
68154
* Notifies the runtime of a change in the connection state
69155
* @param canSendOps - true if the runtime is allowed to send ops
70156
* @param clientId - the ID of the client that is connecting or disconnecting
157+
*
158+
* @remarks
159+
* This is deprecated when used with `@fluidframework/container-loader` v2.63
160+
* and later. Implement {@link IRuntime.setConnectionStatus}. Then this method
161+
* will not be called, when using newer container-loader.
162+
*
163+
* Note: when {@link IRuntime.setConnectionStatus} is implemented, there will
164+
* not be a call exactly when Container loads as happens currently without it.
71165
*/
72166
setConnectionState(canSendOps: boolean, clientId?: string);
73167

168+
/**
169+
* Notifies the runtime of a change in the connection state.
170+
*
171+
* @remarks This supersedes {@link IRuntime.setConnectionState}.
172+
*/
173+
setConnectionStatus?(status: ConnectionStatus): void;
174+
74175
/**
75176
* Processes the given op (message)
76177
* @param message - delta message received from the server
@@ -273,6 +374,16 @@ export interface IContainerContext {
273374
readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
274375
readonly quorum: IQuorumClients;
275376
readonly audience: IAudience;
377+
/**
378+
* Signal-based audience provides a view of the audience that only relies
379+
* on system signals which will be updated more quickly than
380+
* {@link IContainerContext#audience} that relies on ops for write clients.
381+
* Being signal-based the write members are inherently less reliable than
382+
* {@link IContainerContext#audience}.
383+
*
384+
* @system
385+
*/
386+
readonly signalAudience?: IAudience;
276387
readonly loader: ILoader;
277388
// The logger implementation, which would support tagged events, should be provided by the loader.
278389
readonly taggedLogger: ITelemetryBaseLogger;

0 commit comments

Comments
 (0)