@fluid-experimental/attributor 2.1.0 → 2.3.0-288113
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/README.md +2 -2
- package/dist/attributorContracts.d.ts +49 -0
- package/dist/attributorContracts.d.ts.map +1 -0
- package/dist/attributorContracts.js +22 -0
- package/dist/attributorContracts.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/mixinAttributor.d.ts +8 -49
- package/dist/mixinAttributor.d.ts.map +1 -1
- package/dist/mixinAttributor.js +35 -140
- package/dist/mixinAttributor.js.map +1 -1
- package/dist/runtimeAttributor.d.ts +19 -0
- package/dist/runtimeAttributor.d.ts.map +1 -0
- package/dist/runtimeAttributor.js +71 -0
- package/dist/runtimeAttributor.js.map +1 -0
- package/dist/runtimeAttributorDataStoreChannel.d.ts +92 -0
- package/dist/runtimeAttributorDataStoreChannel.d.ts.map +1 -0
- package/dist/runtimeAttributorDataStoreChannel.js +177 -0
- package/dist/runtimeAttributorDataStoreChannel.js.map +1 -0
- package/dist/runtimeAttributorDataStoreFactory.d.ts +15 -0
- package/dist/runtimeAttributorDataStoreFactory.d.ts.map +1 -0
- package/dist/runtimeAttributorDataStoreFactory.js +39 -0
- package/dist/runtimeAttributorDataStoreFactory.js.map +1 -0
- package/lib/attributorContracts.d.ts +49 -0
- package/lib/attributorContracts.d.ts.map +1 -0
- package/lib/attributorContracts.js +19 -0
- package/lib/attributorContracts.js.map +1 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/mixinAttributor.d.ts +8 -49
- package/lib/mixinAttributor.d.ts.map +1 -1
- package/lib/mixinAttributor.js +33 -138
- package/lib/mixinAttributor.js.map +1 -1
- package/lib/runtimeAttributor.d.ts +19 -0
- package/lib/runtimeAttributor.d.ts.map +1 -0
- package/lib/runtimeAttributor.js +67 -0
- package/lib/runtimeAttributor.js.map +1 -0
- package/lib/runtimeAttributorDataStoreChannel.d.ts +92 -0
- package/lib/runtimeAttributorDataStoreChannel.d.ts.map +1 -0
- package/lib/runtimeAttributorDataStoreChannel.js +173 -0
- package/lib/runtimeAttributorDataStoreChannel.js.map +1 -0
- package/lib/runtimeAttributorDataStoreFactory.d.ts +15 -0
- package/lib/runtimeAttributorDataStoreFactory.d.ts.map +1 -0
- package/lib/runtimeAttributorDataStoreFactory.js +35 -0
- package/lib/runtimeAttributorDataStoreFactory.js.map +1 -0
- package/package.json +20 -19
- package/src/attributorContracts.ts +61 -0
- package/src/index.ts +3 -3
- package/src/mixinAttributor.ts +45 -267
- package/src/runtimeAttributor.ts +111 -0
- package/src/runtimeAttributorDataStoreChannel.ts +261 -0
- package/src/runtimeAttributorDataStoreFactory.ts +59 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
7
|
+
import { AttachState, IDeltaManager } from "@fluidframework/container-definitions/internal";
|
|
8
|
+
import { FluidObject, IRequest, IResponse } from "@fluidframework/core-interfaces";
|
|
9
|
+
import type { IFluidHandleInternal } from "@fluidframework/core-interfaces/internal";
|
|
10
|
+
import { assert, Deferred, unreachableCase } from "@fluidframework/core-utils/internal";
|
|
11
|
+
import { FluidObjectHandle } from "@fluidframework/datastore/internal";
|
|
12
|
+
import { IFluidDataStoreRuntimeEvents } from "@fluidframework/datastore-definitions/internal";
|
|
13
|
+
import {
|
|
14
|
+
IDocumentMessage,
|
|
15
|
+
type ISnapshotTree,
|
|
16
|
+
ISequencedDocumentMessage,
|
|
17
|
+
IQuorumClients,
|
|
18
|
+
} from "@fluidframework/driver-definitions/internal";
|
|
19
|
+
import {
|
|
20
|
+
IGarbageCollectionData,
|
|
21
|
+
IFluidDataStoreChannel,
|
|
22
|
+
IFluidDataStoreContext,
|
|
23
|
+
IInboundSignalMessage,
|
|
24
|
+
VisibilityState,
|
|
25
|
+
type ISummaryTreeWithStats,
|
|
26
|
+
type ITelemetryContext,
|
|
27
|
+
} from "@fluidframework/runtime-definitions/internal";
|
|
28
|
+
import {
|
|
29
|
+
ITelemetryLoggerExt,
|
|
30
|
+
MonitoringContext,
|
|
31
|
+
raiseConnectedEvent,
|
|
32
|
+
createChildMonitoringContext,
|
|
33
|
+
} from "@fluidframework/telemetry-utils/internal";
|
|
34
|
+
|
|
35
|
+
import { RuntimeAttributor } from "./runtimeAttributor.js";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Data store channel for the runtime attributor. This channel is responsible for storing and managing the
|
|
39
|
+
*/
|
|
40
|
+
export class RuntimeAttributorDataStoreChannel
|
|
41
|
+
extends TypedEventEmitter<IFluidDataStoreRuntimeEvents>
|
|
42
|
+
implements IFluidDataStoreChannel
|
|
43
|
+
{
|
|
44
|
+
public constructor(
|
|
45
|
+
public readonly dataStoreContext: IFluidDataStoreContext,
|
|
46
|
+
existing: boolean,
|
|
47
|
+
) {
|
|
48
|
+
super();
|
|
49
|
+
this.runtimeAttributor = new RuntimeAttributor();
|
|
50
|
+
this.mc = createChildMonitoringContext({
|
|
51
|
+
logger: dataStoreContext.baseLogger,
|
|
52
|
+
namespace: "Attributor",
|
|
53
|
+
});
|
|
54
|
+
this.attachState = dataStoreContext.attachState;
|
|
55
|
+
if (existing) {
|
|
56
|
+
this.visibilityState =
|
|
57
|
+
dataStoreContext.attachState === AttachState.Detached
|
|
58
|
+
? VisibilityState.LocallyVisible
|
|
59
|
+
: VisibilityState.GloballyVisible;
|
|
60
|
+
} else {
|
|
61
|
+
this.visibilityState = VisibilityState.NotVisible;
|
|
62
|
+
}
|
|
63
|
+
// If it's existing we know it has been attached.
|
|
64
|
+
if (existing) {
|
|
65
|
+
this.deferredAttached.resolve();
|
|
66
|
+
}
|
|
67
|
+
this.entryPoint = new FluidObjectHandle<FluidObject>(
|
|
68
|
+
this.runtimeAttributor,
|
|
69
|
+
"",
|
|
70
|
+
dataStoreContext.IFluidHandleContext,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public get IFluidDataStoreChannel(): IFluidDataStoreChannel {
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private _disposed = false;
|
|
79
|
+
public get disposed(): boolean {
|
|
80
|
+
return this._disposed;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public dispose(): void {
|
|
84
|
+
this._disposed = true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private readonly runtimeAttributor: RuntimeAttributor;
|
|
88
|
+
public isEnabled = true;
|
|
89
|
+
public attachState: AttachState;
|
|
90
|
+
public visibilityState: VisibilityState;
|
|
91
|
+
private readonly deferredAttached = new Deferred<void>();
|
|
92
|
+
private readonly mc: MonitoringContext;
|
|
93
|
+
public get logger(): ITelemetryLoggerExt {
|
|
94
|
+
return this.mc.logger;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public async initialize(
|
|
98
|
+
deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
|
|
99
|
+
quorum: IQuorumClients,
|
|
100
|
+
baseSnapshotForAttributorTree: ISnapshotTree | undefined,
|
|
101
|
+
readBlob: (id: string) => Promise<ArrayBufferLike>,
|
|
102
|
+
): Promise<void> {
|
|
103
|
+
await this.runtimeAttributor.initialize(
|
|
104
|
+
deltaManager,
|
|
105
|
+
quorum,
|
|
106
|
+
baseSnapshotForAttributorTree,
|
|
107
|
+
readBlob,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* {@inheritdoc IFluidDataStoreChannel.makeVisibleAndAttachGraph}
|
|
113
|
+
*/
|
|
114
|
+
public makeVisibleAndAttachGraph(): void {
|
|
115
|
+
if (this.visibilityState !== VisibilityState.NotVisible) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this.visibilityState = VisibilityState.LocallyVisible;
|
|
119
|
+
|
|
120
|
+
this.dataStoreContext.makeLocallyVisible();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* {@inheritdoc IFluidDataStoreChannel.getAttachSummary}
|
|
125
|
+
*/
|
|
126
|
+
public getAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {
|
|
127
|
+
return this.runtimeAttributor.summarizeOpAttributor();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* {@inheritdoc IFluidDataStoreChannel.getAttachGCData}
|
|
132
|
+
*/
|
|
133
|
+
public getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {
|
|
134
|
+
return { gcNodes: {} };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* {@inheritdoc IFluidDataStoreChannel.process}
|
|
139
|
+
*/
|
|
140
|
+
public process(
|
|
141
|
+
message: ISequencedDocumentMessage,
|
|
142
|
+
local: boolean,
|
|
143
|
+
localOpMetadata: unknown,
|
|
144
|
+
): void {
|
|
145
|
+
throw new Error("Attributor should not receive messages yet");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* {@inheritdoc IFluidDataStoreChannel.processSignal}
|
|
150
|
+
*/
|
|
151
|
+
public processSignal(message: IInboundSignalMessage, local: boolean): void {
|
|
152
|
+
throw new Error("Attributor should not receive signals");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* {@inheritdoc IFluidDataStoreChannel.summarize}
|
|
157
|
+
*/
|
|
158
|
+
public async summarize(
|
|
159
|
+
fullTree?: boolean,
|
|
160
|
+
trackState?: boolean,
|
|
161
|
+
telemetryContext?: ITelemetryContext,
|
|
162
|
+
): Promise<ISummaryTreeWithStats> {
|
|
163
|
+
return this.runtimeAttributor.summarizeOpAttributor();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* {@inheritdoc IFluidDataStoreChannel.getGCData}
|
|
168
|
+
*/
|
|
169
|
+
public async getGCData(fullGC?: boolean): Promise<IGarbageCollectionData> {
|
|
170
|
+
// Nothing to be GCed from the attributor.
|
|
171
|
+
const garbageCollectionData: IGarbageCollectionData = { gcNodes: {} };
|
|
172
|
+
return garbageCollectionData;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* {@inheritdoc IFluidDataStoreChannel.updateUsedRoutes}
|
|
177
|
+
*/
|
|
178
|
+
public updateUsedRoutes(usedRoutes: string[]): void {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* {@inheritdoc IFluidDataStoreChannel.setConnectionState}
|
|
184
|
+
*/
|
|
185
|
+
public setConnectionState(connected: boolean, clientId?: string): void {
|
|
186
|
+
raiseConnectedEvent(this.logger, this, connected, clientId);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* {@inheritdoc IFluidDataStoreChannel.reSubmit}
|
|
191
|
+
*/
|
|
192
|
+
public reSubmit(type: string, content: unknown, localOpMetadata: unknown): void {
|
|
193
|
+
// Should not resubmit anything from the attributor as the attributor does not send ops yet.
|
|
194
|
+
throw new Error("Should not resubmit anything from the attributor");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* {@inheritdoc IFluidDataStoreChannel.applyStashedOp}
|
|
199
|
+
*/
|
|
200
|
+
public async applyStashedOp(content: unknown): Promise<unknown> {
|
|
201
|
+
// Should not apply stashed ops to the attributor as the attributor does not send ops yet.
|
|
202
|
+
throw new Error("Should not apply stashed ops to the attributor");
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* {@inheritdoc IFluidDataStoreChannel.rollback}
|
|
207
|
+
*/
|
|
208
|
+
public rollback?(type: string, content: unknown, localOpMetadata: unknown): void {
|
|
209
|
+
// Should not rollback anything from the attributor as it does not send ops yet.
|
|
210
|
+
throw new Error("Should not rollback anything from the attributor");
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* {@inheritdoc IFluidDataStoreChannel.entryPoint}
|
|
215
|
+
*/
|
|
216
|
+
public readonly entryPoint: IFluidHandleInternal<FluidObject>;
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* {@inheritdoc IFluidDataStoreChannel.request}
|
|
220
|
+
*/
|
|
221
|
+
public async request(request: IRequest): Promise<IResponse> {
|
|
222
|
+
// Should not request anything from the attributor as the attributor does not have any channels further.
|
|
223
|
+
throw new Error("Should not request anything from the attributor");
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* {@inheritdoc IFluidDataStoreChannel.setAttachState}
|
|
228
|
+
*/
|
|
229
|
+
public setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {
|
|
230
|
+
switch (attachState) {
|
|
231
|
+
case AttachState.Attaching: {
|
|
232
|
+
this.attachState = AttachState.Attaching;
|
|
233
|
+
|
|
234
|
+
assert(
|
|
235
|
+
this.visibilityState === VisibilityState.LocallyVisible,
|
|
236
|
+
0xa1e /* Data store should be locally visible before it can become globally visible. */,
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
// Mark the data store globally visible and make its child channels visible as well.
|
|
240
|
+
this.visibilityState = VisibilityState.GloballyVisible;
|
|
241
|
+
|
|
242
|
+
// This promise resolution will be moved to attached event once we fix the scheduler.
|
|
243
|
+
this.deferredAttached.resolve();
|
|
244
|
+
this.emit("attaching");
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
case AttachState.Attached: {
|
|
248
|
+
assert(
|
|
249
|
+
this.visibilityState === VisibilityState.GloballyVisible,
|
|
250
|
+
0xa1f /* Data store should be globally visible when its attached. */,
|
|
251
|
+
);
|
|
252
|
+
this.attachState = AttachState.Attached;
|
|
253
|
+
this.emit("attached");
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
default: {
|
|
257
|
+
unreachableCase(attachState, "unreached");
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
IFluidDataStoreFactory,
|
|
8
|
+
IFluidDataStoreChannel,
|
|
9
|
+
IFluidDataStoreContext,
|
|
10
|
+
} from "@fluidframework/runtime-definitions/internal";
|
|
11
|
+
import { PerformanceEvent, createChildLogger } from "@fluidframework/telemetry-utils/internal";
|
|
12
|
+
|
|
13
|
+
import { RuntimeAttributorDataStoreChannel } from "./runtimeAttributorDataStoreChannel.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Factory for the runtime attributor data store channel.
|
|
17
|
+
*/
|
|
18
|
+
export class RuntimeAttributorFactory implements IFluidDataStoreFactory {
|
|
19
|
+
public static readonly type = "@fluid-experimental/attributor";
|
|
20
|
+
|
|
21
|
+
public get type(): string {
|
|
22
|
+
return RuntimeAttributorFactory.type;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public get IFluidDataStoreFactory(): IFluidDataStoreFactory {
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public async instantiateDataStore(
|
|
30
|
+
context: IFluidDataStoreContext,
|
|
31
|
+
existing: boolean,
|
|
32
|
+
): Promise<IFluidDataStoreChannel> {
|
|
33
|
+
const runtime = new RuntimeAttributorDataStoreChannel(context, existing);
|
|
34
|
+
|
|
35
|
+
const logger = createChildLogger({
|
|
36
|
+
logger: context.baseLogger,
|
|
37
|
+
namespace: "Attributor",
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
await PerformanceEvent.timedExecAsync(
|
|
41
|
+
logger,
|
|
42
|
+
{
|
|
43
|
+
eventName: "initialize",
|
|
44
|
+
},
|
|
45
|
+
async (event) => {
|
|
46
|
+
await runtime.initialize(
|
|
47
|
+
context.deltaManager,
|
|
48
|
+
context.getQuorum(),
|
|
49
|
+
context.baseSnapshot,
|
|
50
|
+
async (id: string) => context.storage.readBlob(id),
|
|
51
|
+
);
|
|
52
|
+
event.end({
|
|
53
|
+
attributionEnabledInDoc: true, // If we are instantiating the attributor, it is enabled
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
return runtime;
|
|
58
|
+
}
|
|
59
|
+
}
|