Skip to content

Commit 8c11bdc

Browse files
refactor: split out TreeKernel from the SharedObject class hierarchy (#23837)
## Description Split out SharedTree logic into a "kernel" similar to how SharedMap does it. This makes shared tree easier to reuse in other SharedObjects like adapters.
1 parent cd8be52 commit 8c11bdc

File tree

5 files changed

+427
-182
lines changed

5 files changed

+427
-182
lines changed

packages/dds/tree/src/shared-tree-core/sharedTreeCore.ts

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import { assert } from "@fluidframework/core-utils/internal";
77
import type {
8-
IChannelAttributes,
98
IFluidDataStoreRuntime,
109
IChannelStorageService,
1110
} from "@fluidframework/datastore-definitions/internal";
@@ -17,10 +16,7 @@ import type {
1716
ITelemetryContext,
1817
} from "@fluidframework/runtime-definitions/internal";
1918
import { SummaryTreeBuilder } from "@fluidframework/runtime-utils/internal";
20-
import {
21-
type IFluidSerializer,
22-
SharedObject,
23-
} from "@fluidframework/shared-object-base/internal";
19+
import type { IFluidSerializer } from "@fluidframework/shared-object-base/internal";
2420

2521
import type { ICodecOptions, IJsonCodec } from "../codec/index.js";
2622
import {
@@ -38,7 +34,7 @@ import {
3834
import {
3935
type JsonCompatibleReadOnly,
4036
brand,
41-
Breakable,
37+
type Breakable,
4238
type WithBreakable,
4339
throwIfBroken,
4440
breakingClass,
@@ -56,6 +52,8 @@ import type { ResubmitMachine } from "./resubmitMachine.js";
5652
import { DefaultResubmitMachine } from "./defaultResubmitMachine.js";
5753
import { BranchCommitEnricher } from "./branchCommitEnricher.js";
5854
import { createChildLogger } from "@fluidframework/telemetry-utils/internal";
55+
import type { IFluidLoadable, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
56+
import type { IChannelView } from "../shared-tree/index.js";
5957

6058
// TODO: Organize this to be adjacent to persisted types.
6159
const summarizablesTreeKey = "indexes";
@@ -74,11 +72,8 @@ export interface ClonableSchemaAndPolicy extends SchemaAndPolicy {
7472
*/
7573
@breakingClass
7674
export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
77-
extends SharedObject
7875
implements WithBreakable
7976
{
80-
public readonly breaker: Breakable = new Breakable("Shared Tree");
81-
8277
private readonly editManager: EditManager<TEditor, TChange, ChangeFamily<TEditor, TChange>>;
8378
private readonly summarizables: readonly [EditManagerSummarizer<TChange>, ...Summarizable[]];
8479
/**
@@ -88,14 +83,6 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
8883
*/
8984
private detachedRevision: SeqNumber | undefined = minimumPossibleSequenceNumber;
9085

91-
/**
92-
* Used to edit the state of the tree. Edits will be immediately applied locally to the tree.
93-
* If there is no transaction currently ongoing, then the edits will be submitted to Fluid immediately as well.
94-
*/
95-
public get editor(): TEditor {
96-
return this.getLocalBranch().editor;
97-
}
98-
9986
/**
10087
* Used to encode/decode messages sent to/received from the Fluid runtime.
10188
*
@@ -115,45 +102,44 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
115102
private readonly idCompressor: IIdCompressor;
116103

117104
private readonly resubmitMachine: ResubmitMachine<TChange>;
118-
protected readonly commitEnricher: BranchCommitEnricher<TChange>;
105+
public readonly commitEnricher: BranchCommitEnricher<TChange>;
119106

120-
protected readonly mintRevisionTag: () => RevisionTag;
107+
public readonly mintRevisionTag: () => RevisionTag;
121108

122109
private readonly schemaAndPolicy: ClonableSchemaAndPolicy;
123110

124111
/**
125112
* @param summarizables - Summarizers for all indexes used by this tree
126113
* @param changeFamily - The change family
127114
* @param editManager - The edit manager
128-
* @param id - The id of the shared object
129115
* @param runtime - The IFluidDataStoreRuntime which contains the shared object
130-
* @param attributes - Attributes of the shared object
131-
* @param telemetryContextPrefix - The property prefix for telemetry pertaining to this object. See {@link ITelemetryContext}
116+
* @param editor - Used to edit the state of the tree. Edits will be immediately applied locally to the tree.
117+
* If there is no transaction currently ongoing, then the edits will be submitted to Fluid immediately as well.
132118
*/
133119
public constructor(
120+
public readonly breaker: Breakable,
121+
public readonly sharedObject: IChannelView & IFluidLoadable,
122+
public readonly serializer: IFluidSerializer,
123+
public readonly submitLocalMessage: (content: unknown, localOpMetadata?: unknown) => void,
124+
logger: ITelemetryBaseLogger | undefined,
134125
summarizables: readonly Summarizable[],
135126
changeFamily: ChangeFamily<TEditor, TChange>,
136127
options: ICodecOptions,
137128
formatOptions: ExplicitCoreCodecVersions,
138-
// Base class arguments
139-
id: string,
140129
runtime: IFluidDataStoreRuntime,
141-
attributes: IChannelAttributes,
142-
telemetryContextPrefix: string,
143130
schema: TreeStoredSchemaRepository,
144131
schemaPolicy: SchemaPolicy,
145132
resubmitMachine?: ResubmitMachine<TChange>,
146133
enricher?: ChangeEnricherReadonlyCheckout<TChange>,
134+
public readonly getEditor: () => TEditor = () => this.getLocalBranch().editor,
147135
) {
148-
super(id, runtime, attributes, telemetryContextPrefix);
149-
150136
this.schemaAndPolicy = {
151137
schema,
152138
policy: schemaPolicy,
153139
};
154140

155141
const rebaseLogger = createChildLogger({
156-
logger: this.logger,
142+
logger,
157143
namespace: "Rebase",
158144
});
159145

@@ -230,7 +216,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
230216
// TODO: SharedObject's merging of the two summary methods into summarizeCore is not what we want here:
231217
// We might want to not subclass it, or override/reimplement most of its functionality.
232218
@throwIfBroken
233-
protected summarizeCore(
219+
public summarizeCore(
234220
serializer: IFluidSerializer,
235221
telemetryContext?: ITelemetryContext,
236222
incrementalSummaryContext?: IExperimentalIncrementalSummaryContext,
@@ -242,7 +228,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
242228
summarizableBuilder.addWithStats(
243229
s.key,
244230
s.getAttachSummary(
245-
(contents) => serializer.stringify(contents, this.handle),
231+
(contents) => serializer.stringify(contents, this.sharedObject.handle),
246232
undefined,
247233
undefined,
248234
telemetryContext,
@@ -255,7 +241,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
255241
return builder.getSummaryTree();
256242
}
257243

258-
protected async loadCore(services: IChannelStorageService): Promise<void> {
244+
public async loadCore(services: IChannelStorageService): Promise<void> {
259245
assert(
260246
this.editManager.localBranch.getHead() === this.editManager.getTrunkHead(),
261247
0xaaa /* All local changes should be applied to the trunk before loading from summary */,
@@ -310,7 +296,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
310296
isResubmit: boolean,
311297
): void {
312298
assert(
313-
this.isAttached() === (this.detachedRevision === undefined),
299+
this.sharedObject.isAttached() === (this.detachedRevision === undefined),
314300
0x95a /* Detached revision should only be set when not attached */,
315301
);
316302

@@ -351,7 +337,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
351337
this.resubmitMachine.onCommitSubmitted(enrichedCommit);
352338
}
353339

354-
protected processCore(
340+
public processCore(
355341
message: ISequencedDocumentMessage,
356342
local: boolean,
357343
localOpMetadata: unknown,
@@ -371,20 +357,15 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
371357
this.editManager.advanceMinimumSequenceNumber(brand(message.minimumSequenceNumber));
372358
}
373359

374-
protected getLocalBranch(): SharedTreeBranch<TEditor, TChange> {
360+
public getLocalBranch(): SharedTreeBranch<TEditor, TChange> {
375361
return this.editManager.localBranch;
376362
}
377363

378-
protected onDisconnect(): void {}
379-
380-
protected override didAttach(): void {
364+
public didAttach(): void {
381365
this.detachedRevision = undefined;
382366
}
383367

384-
protected override reSubmitCore(
385-
content: JsonCompatibleReadOnly,
386-
localOpMetadata: unknown,
387-
): void {
368+
public reSubmitCore(content: JsonCompatibleReadOnly, localOpMetadata: unknown): void {
388369
// Empty context object is passed in, as our decode function is schema-agnostic.
389370
const {
390371
commit: { revision },
@@ -413,7 +394,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
413394
this.submitCommit(enrichedCommit, localOpMetadata, true);
414395
}
415396

416-
protected applyStashedOp(content: JsonCompatibleReadOnly): void {
397+
public applyStashedOp(content: JsonCompatibleReadOnly): void {
417398
// Empty context object is passed in, as our decode function is schema-agnostic.
418399
const {
419400
commit: { revision, change },

0 commit comments

Comments
 (0)