@fluidframework/routerlicious-driver 2.3.0-288113 → 2.3.0
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/dist/createNewUtils.d.ts.map +1 -1
- package/dist/createNewUtils.js +3 -1
- package/dist/createNewUtils.js.map +1 -1
- package/dist/deltaStorageService.js +1 -1
- package/dist/deltaStorageService.js.map +1 -1
- package/dist/documentService.d.ts +6 -11
- package/dist/documentService.d.ts.map +1 -1
- package/dist/documentService.js +16 -61
- package/dist/documentService.js.map +1 -1
- package/dist/documentServiceFactory.d.ts +1 -0
- package/dist/documentServiceFactory.d.ts.map +1 -1
- package/dist/documentServiceFactory.js +33 -42
- package/dist/documentServiceFactory.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/r11sSnapshotParser.d.ts.map +1 -1
- package/dist/r11sSnapshotParser.js +2 -4
- package/dist/r11sSnapshotParser.js.map +1 -1
- package/dist/sessionInfoManager.d.ts +55 -0
- package/dist/sessionInfoManager.d.ts.map +1 -0
- package/dist/sessionInfoManager.js +100 -0
- package/dist/sessionInfoManager.js.map +1 -0
- package/dist/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
- package/dist/shreddedSummaryDocumentStorageService.js +3 -4
- package/dist/shreddedSummaryDocumentStorageService.js.map +1 -1
- package/dist/summaryTreeUploadManager.d.ts.map +1 -1
- package/dist/summaryTreeUploadManager.js +3 -3
- package/dist/summaryTreeUploadManager.js.map +1 -1
- package/dist/urlUtils.d.ts.map +1 -1
- package/dist/urlUtils.js +0 -2
- package/dist/urlUtils.js.map +1 -1
- package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
- package/dist/wholeSummaryDocumentStorageService.js +3 -4
- package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
- package/lib/createNewUtils.d.ts.map +1 -1
- package/lib/createNewUtils.js +3 -1
- package/lib/createNewUtils.js.map +1 -1
- package/lib/deltaStorageService.js +1 -1
- package/lib/deltaStorageService.js.map +1 -1
- package/lib/documentService.d.ts +6 -11
- package/lib/documentService.d.ts.map +1 -1
- package/lib/documentService.js +16 -61
- package/lib/documentService.js.map +1 -1
- package/lib/documentServiceFactory.d.ts +1 -0
- package/lib/documentServiceFactory.d.ts.map +1 -1
- package/lib/documentServiceFactory.js +19 -28
- package/lib/documentServiceFactory.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/r11sSnapshotParser.d.ts.map +1 -1
- package/lib/r11sSnapshotParser.js +2 -4
- package/lib/r11sSnapshotParser.js.map +1 -1
- package/lib/sessionInfoManager.d.ts +55 -0
- package/lib/sessionInfoManager.d.ts.map +1 -0
- package/lib/sessionInfoManager.js +96 -0
- package/lib/sessionInfoManager.js.map +1 -0
- package/lib/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
- package/lib/shreddedSummaryDocumentStorageService.js +3 -4
- package/lib/shreddedSummaryDocumentStorageService.js.map +1 -1
- package/lib/summaryTreeUploadManager.d.ts.map +1 -1
- package/lib/summaryTreeUploadManager.js +3 -3
- package/lib/summaryTreeUploadManager.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/urlUtils.d.ts.map +1 -1
- package/lib/urlUtils.js +0 -2
- package/lib/urlUtils.js.map +1 -1
- package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
- package/lib/wholeSummaryDocumentStorageService.js +3 -4
- package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
- package/package.json +16 -15
- package/src/createNewUtils.ts +4 -1
- package/src/deltaStorageService.ts +1 -1
- package/src/documentService.ts +19 -75
- package/src/documentServiceFactory.ts +25 -38
- package/src/packageVersion.ts +1 -1
- package/src/r11sSnapshotParser.ts +3 -5
- package/src/sessionInfoManager.ts +148 -0
- package/src/shreddedSummaryDocumentStorageService.ts +3 -4
- package/src/summaryTreeUploadManager.ts +4 -4
- package/src/urlUtils.ts +2 -4
- package/src/wholeSummaryDocumentStorageService.ts +3 -4
- package/tsconfig.json +1 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { assert } from "@fluidframework/core-utils/internal";
|
|
7
|
+
import { getW3CData } from "@fluidframework/driver-base/internal";
|
|
8
|
+
import { IResolvedUrl } from "@fluidframework/driver-definitions/internal";
|
|
9
|
+
import { ISession } from "@fluidframework/server-services-client";
|
|
10
|
+
import {
|
|
11
|
+
PerformanceEvent,
|
|
12
|
+
ITelemetryLoggerExt,
|
|
13
|
+
} from "@fluidframework/telemetry-utils/internal";
|
|
14
|
+
|
|
15
|
+
import { RouterliciousOrdererRestWrapper } from "./restWrapper.js";
|
|
16
|
+
import { getDiscoveredFluidResolvedUrl } from "./urlUtils.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Amount of time between discoveries within which we don't need to rediscover on re-connect.
|
|
20
|
+
* Currently, R11s defines session length at 10 minutes. To avoid any weird unknown edge-cases though,
|
|
21
|
+
* we set the limit to 5 minutes here.
|
|
22
|
+
* In the future, we likely want to retrieve this information from service's "inactive session" definition.
|
|
23
|
+
*/
|
|
24
|
+
export const RediscoverAfterTimeSinceDiscoveryMs = 5 * 60000; // 5 minutes
|
|
25
|
+
|
|
26
|
+
interface IGetSessionInfoParams {
|
|
27
|
+
resolvedUrl: IResolvedUrl;
|
|
28
|
+
documentId: string;
|
|
29
|
+
tenantId: string;
|
|
30
|
+
ordererRestWrapper: RouterliciousOrdererRestWrapper;
|
|
31
|
+
logger: ITelemetryLoggerExt;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface IGetSessionInfoResponse {
|
|
35
|
+
refreshed: boolean;
|
|
36
|
+
resolvedUrl: IResolvedUrl;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class SessionInfoManager {
|
|
40
|
+
/**
|
|
41
|
+
* Stored session info
|
|
42
|
+
* Key: URL for given session (see "getDiscoverSessionUrl")
|
|
43
|
+
* Value: session info stored as an IResolvedUrl
|
|
44
|
+
*/
|
|
45
|
+
private readonly sessionInfoMap: Map<string, IResolvedUrl> = new Map();
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Stored dates of when a session was last discovered/refreshed
|
|
49
|
+
* Key: URL for given session (see "getDiscoverSessionUrl")
|
|
50
|
+
* Value: date last discovered
|
|
51
|
+
*/
|
|
52
|
+
private readonly sessionLastDiscoveredMap: Map<string, number> = new Map();
|
|
53
|
+
|
|
54
|
+
constructor(private readonly enableDiscovery: boolean) {}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Start tracking info for a given session
|
|
58
|
+
*/
|
|
59
|
+
public async initializeSessionInfo(
|
|
60
|
+
params: IGetSessionInfoParams & { session: ISession | undefined },
|
|
61
|
+
): Promise<IResolvedUrl> {
|
|
62
|
+
const { resolvedUrl, session } = params;
|
|
63
|
+
|
|
64
|
+
const url = getDiscoverSessionUrl(params);
|
|
65
|
+
assert(
|
|
66
|
+
this.sessionInfoMap.has(url) === this.sessionLastDiscoveredMap.has(url),
|
|
67
|
+
0xa2d /* Session map state mismatch */,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
if (session !== undefined) {
|
|
71
|
+
this.sessionInfoMap.set(url, getDiscoveredFluidResolvedUrl(resolvedUrl, session));
|
|
72
|
+
this.sessionLastDiscoveredMap.set(url, Date.now());
|
|
73
|
+
} else if (!this.sessionInfoMap.has(url)) {
|
|
74
|
+
this.sessionInfoMap.set(url, resolvedUrl);
|
|
75
|
+
// Force a refresh
|
|
76
|
+
this.sessionLastDiscoveredMap.set(url, 0);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return (await this.getSessionInfo(params)).resolvedUrl;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Retrieve, and potentially refresh, info of a given session
|
|
84
|
+
*/
|
|
85
|
+
public async getSessionInfo(
|
|
86
|
+
params: IGetSessionInfoParams,
|
|
87
|
+
): Promise<IGetSessionInfoResponse> {
|
|
88
|
+
const url = getDiscoverSessionUrl(params);
|
|
89
|
+
assert(
|
|
90
|
+
this.sessionInfoMap.has(url) && this.sessionLastDiscoveredMap.has(url),
|
|
91
|
+
0xa2e /* Unexpected discover session URL */,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
let refreshed = false;
|
|
95
|
+
const shouldRediscover =
|
|
96
|
+
Date.now() - this.sessionLastDiscoveredMap.get(url)! >
|
|
97
|
+
RediscoverAfterTimeSinceDiscoveryMs;
|
|
98
|
+
if (this.enableDiscovery && shouldRediscover) {
|
|
99
|
+
await this.fetchAndUpdateSessionInfo(params).catch((error) => {
|
|
100
|
+
// Undo discovery time set on failure, so that next check refreshes.
|
|
101
|
+
this.sessionLastDiscoveredMap.set(url, 0);
|
|
102
|
+
throw error;
|
|
103
|
+
});
|
|
104
|
+
refreshed = true;
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
refreshed,
|
|
108
|
+
// ! Shallow copy is important as some mechanisms may rely on object comparison
|
|
109
|
+
resolvedUrl: { ...this.sessionInfoMap.get(url)! },
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private async fetchAndUpdateSessionInfo(params: IGetSessionInfoParams): Promise<void> {
|
|
114
|
+
const { documentId, ordererRestWrapper, logger, resolvedUrl } = params;
|
|
115
|
+
|
|
116
|
+
const url = getDiscoverSessionUrl(params);
|
|
117
|
+
const discoveredSession = await PerformanceEvent.timedExecAsync(
|
|
118
|
+
logger,
|
|
119
|
+
{
|
|
120
|
+
eventName: "DiscoverSession",
|
|
121
|
+
docId: documentId,
|
|
122
|
+
},
|
|
123
|
+
async (event) => {
|
|
124
|
+
// The service responds with the current document session associated with the container.
|
|
125
|
+
const response = await ordererRestWrapper.get<ISession>(url);
|
|
126
|
+
event.end({
|
|
127
|
+
...response.propsToLog,
|
|
128
|
+
...getW3CData(response.requestUrl, "xmlhttprequest"),
|
|
129
|
+
});
|
|
130
|
+
return response.content;
|
|
131
|
+
},
|
|
132
|
+
);
|
|
133
|
+
this.sessionInfoMap.set(
|
|
134
|
+
url,
|
|
135
|
+
getDiscoveredFluidResolvedUrl(resolvedUrl, discoveredSession),
|
|
136
|
+
);
|
|
137
|
+
this.sessionLastDiscoveredMap.set(url, Date.now());
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function getDiscoverSessionUrl(params: {
|
|
142
|
+
resolvedUrl: IResolvedUrl;
|
|
143
|
+
tenantId: string;
|
|
144
|
+
documentId: string;
|
|
145
|
+
}): string {
|
|
146
|
+
const { resolvedUrl, tenantId, documentId } = params;
|
|
147
|
+
return `${resolvedUrl.endpoints.ordererUrl}/documents/${tenantId}/session/${documentId}`;
|
|
148
|
+
}
|
|
@@ -98,14 +98,13 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
|
|
|
98
98
|
|
|
99
99
|
public async getSnapshotTree(version?: IVersion): Promise<ISnapshotTreeEx | null> {
|
|
100
100
|
let requestVersion = version;
|
|
101
|
-
if (requestVersion
|
|
101
|
+
if (!requestVersion) {
|
|
102
102
|
const versions = await this.getVersions(this.id, 1);
|
|
103
|
-
|
|
104
|
-
if (firstVersion === undefined) {
|
|
103
|
+
if (versions.length === 0) {
|
|
105
104
|
return null;
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
requestVersion =
|
|
107
|
+
requestVersion = versions[0];
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
const cachedSnapshotTree = await this.snapshotTreeCache?.get(
|
|
@@ -41,7 +41,8 @@ export class SummaryTreeUploadManager implements ISummaryUploadManager {
|
|
|
41
41
|
previousFullSnapshot: ISnapshotTreeEx | undefined,
|
|
42
42
|
): Promise<string> {
|
|
43
43
|
const entries = await Promise.all(
|
|
44
|
-
Object.
|
|
44
|
+
Object.keys(summaryTree.tree).map(async (key) => {
|
|
45
|
+
const entry = summaryTree.tree[key];
|
|
45
46
|
const pathHandle = await this.writeSummaryTreeObject(entry, previousFullSnapshot);
|
|
46
47
|
const treeEntry: IGitCreateTreeEntry = {
|
|
47
48
|
mode: getGitMode(entry),
|
|
@@ -122,8 +123,8 @@ export class SummaryTreeUploadManager implements ISummaryUploadManager {
|
|
|
122
123
|
/** Previous snapshot, subtree relative to this path part */
|
|
123
124
|
previousSnapshot: ISnapshotTreeEx,
|
|
124
125
|
): string {
|
|
126
|
+
assert(path.length > 0, 0x0b3 /* "Expected at least 1 path part" */);
|
|
125
127
|
const key = path[0];
|
|
126
|
-
assert(path.length > 0 && key !== undefined, 0x0b3 /* "Expected at least 1 path part" */);
|
|
127
128
|
if (path.length === 1) {
|
|
128
129
|
switch (handleType) {
|
|
129
130
|
case SummaryType.Blob: {
|
|
@@ -146,7 +147,6 @@ export class SummaryTreeUploadManager implements ISummaryUploadManager {
|
|
|
146
147
|
throw Error(`Unexpected handle summary object type: "${handleType}".`);
|
|
147
148
|
}
|
|
148
149
|
}
|
|
149
|
-
|
|
150
|
-
return this.getIdFromPathCore(handleType, path.slice(1), previousSnapshot.trees[key]!);
|
|
150
|
+
return this.getIdFromPathCore(handleType, path.slice(1), previousSnapshot.trees[key]);
|
|
151
151
|
}
|
|
152
152
|
}
|
package/src/urlUtils.ts
CHANGED
|
@@ -20,13 +20,11 @@ export const getDiscoveredFluidResolvedUrl = (
|
|
|
20
20
|
session: ISession,
|
|
21
21
|
): IResolvedUrl => {
|
|
22
22
|
const discoveredOrdererUrl = new URL(session.ordererUrl);
|
|
23
|
-
|
|
24
|
-
const deltaStorageUrl = new URL(resolvedUrl.endpoints.deltaStorageUrl!);
|
|
23
|
+
const deltaStorageUrl = new URL(resolvedUrl.endpoints.deltaStorageUrl);
|
|
25
24
|
deltaStorageUrl.host = discoveredOrdererUrl.host;
|
|
26
25
|
|
|
27
26
|
const discoveredStorageUrl = new URL(session.historianUrl);
|
|
28
|
-
|
|
29
|
-
const storageUrl = new URL(resolvedUrl.endpoints.storageUrl!);
|
|
27
|
+
const storageUrl = new URL(resolvedUrl.endpoints.storageUrl);
|
|
30
28
|
storageUrl.host = discoveredStorageUrl.host;
|
|
31
29
|
|
|
32
30
|
const parsedUrl = new URL(resolvedUrl.url);
|
|
@@ -161,14 +161,13 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
|
|
|
161
161
|
// eslint-disable-next-line @rushstack/no-new-null
|
|
162
162
|
public async getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null> {
|
|
163
163
|
let requestVersion = version;
|
|
164
|
-
if (requestVersion
|
|
164
|
+
if (!requestVersion) {
|
|
165
165
|
const versions = await this.getVersions(this.id, 1);
|
|
166
|
-
|
|
167
|
-
if (firstVersion === undefined) {
|
|
166
|
+
if (versions.length === 0) {
|
|
168
167
|
return null;
|
|
169
168
|
}
|
|
170
169
|
|
|
171
|
-
requestVersion =
|
|
170
|
+
requestVersion = versions[0];
|
|
172
171
|
}
|
|
173
172
|
|
|
174
173
|
let normalizedWholeSnapshot = await this.snapshotTreeCache.get(
|