Skip to content

Commit be7adca

Browse files
authored
Merge pull request #279103 from MicrosoftDocs/repo_sync_working_branch
Confirm merge from repo_sync_working_branch to main to sync with https://github.com/MicrosoftDocs/azure-docs (branch main)
2 parents 43d11fb + ec27d8b commit be7adca

File tree

1 file changed

+53
-39
lines changed

1 file changed

+53
-39
lines changed

articles/azure-fluid-relay/how-tos/container-recovery.md

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,55 +12,69 @@ In this scenario, we explore data recovery. We consider data to be corrupted whe
1212

1313
## How Fluid Framework and Azure Fluid Relay save state
1414

15-
Fluid framework periodically saves state, called summary, without any explicit backup action initiated by the user. This workflow occurs every one (1) minute if there's no user activity, or sooner if there are more than 1000 pending ops present. Each pending op roughly translates to an individual user action (select, text input etc.) that wasn't summarized yet.
15+
Fluid Framework periodically saves snapshots of the data in the container, which summarize all changes made to the data up to that point. During normal loading the latest snapshot is retrieved, and any subsequent changes are applied on top of that state.
16+
17+
If the latest snapshot or subsequent changes are corrupt, Fluid may not be able to load them normally. In this case, Fluid offers a collection of APIs to view the stored snapshot versions and load them in a view-only mode with no subsequent changes applied. This allows the data to be extracted and optionally injected into a new container to resume collaboration.
1618

1719
## Azure client APIs
1820

19-
We added the following methods to AzureClient that enable developers to recover data from corrupted containers.
21+
### APIs for viewing and loading container versions
2022

21-
`getContainerVersions(ID, options)`
23+
The AzureClient has the following methods to support this scenario:
2224

23-
`getContainerVersions` allows developers to view the previously generated versions of the container.
25+
#### Get container versions
2426

25-
`copyContainer(ID, containerSchema)`
27+
`getContainerVersions(id, options?)`
2628

27-
`copyContainer` allows developers to generate a new detached container from a specific version of another container.
29+
Retrieve a list of available versions that may be loaded from.
2830

29-
## Example recovery flow
31+
`Parameters:`
3032

31-
```typescript
33+
* `id`: The container ID. This is the same ID used when calling `getContainer`.
34+
* `options?`: Optionally, an options object to specify:
35+
* `maxCount`: The maximum number of versions to retrieve. If there are more versions available than requested, the newest versions will be retrieved. **Default: 5**
36+
37+
`Returns:` A promise which resolves to an array of objects that represent available versions (sorted newest to oldest). The objects have the following properties:
38+
39+
* `id`: The version ID.
40+
* *Note*: This is different from the container ID, and specifically references a snapshot version rather than the container.
41+
* `date`: The timestamp when the version was generated.
42+
43+
#### View container version
44+
45+
`viewContainerVersion(id, containerSchema, version, compatibilityMode)`
46+
47+
Load a specific version of a container for viewing only. Any version retrieved from `getContainerVersions` may be used, but for the purpose of recovering corrupted data it is recommended to start with the most-recent version and work backwards to find the most-recent uncorrupted version.
3248

33-
async function recoverDoc(
34-
client: AzureClient,
35-
orgContainerId: string,
36-
containerScema: ContainerSchema,
37-
): Promise<string> {
38-
/* Collect doc versions */
39-
let versions: AzureContainerVersion[] = [];
40-
try {
41-
versions = await client.getContainerVersions(orgContainerId);
42-
} catch (e) {
43-
return Promise.reject(new Error("Unable to get container versions."));
44-
}
45-
46-
for (const version of versions) {
47-
/* Versions are returned in chronological order.
48-
Attempt to copy doc from next available version */
49-
try {
50-
const { container: newContainer } = await client.copyContainer(
51-
orgContainerId,
52-
containerSchema,
53-
version,
54-
);
55-
return await newContainer.attach();
56-
} catch (e) {
57-
// Error. Keep going.
58-
}
59-
}
60-
61-
return Promise.reject(new Error("Could not recreate document"));
62-
}
49+
The container is loaded in a paused state, meaning it will not apply the subsequent changes to the data that happened after the generation of that snapshot. When loaded in this state the container data may be read, but not edited.
6350

51+
`Parameters:`
52+
53+
* `id`: The container ID. This is the same ID used when calling `getContainer`.
54+
* `containerSchema`: The container schema. This is the same schema used when calling `getContainer`.
55+
* `version`: The version object referencing the version to load from. The version object can be retrieved via `getContainerVersions`.
56+
* `compatibilityMode`: The compatibility mode. This is the same compatibility mode used when calling `getContainer`.
57+
58+
`Returns:` A promise which resolves to an object representing the loaded container with a single property:
59+
60+
* `container`: The container object. This is the same type of object as the container object returned by `getContainer`, but is paused in its prior state from the selected version.
61+
62+
### Example
63+
64+
```typescript
65+
const azureClient = new AzureClient(/* ... */);
66+
const versions = await azureClient.getContainerVersions(id);
67+
// Since the versions are sorted in order from newest to oldest, versions[0] will attempt to load the most recent version.
68+
// If the most recent version is corrupted, we could try again with versions[1] and so on to find the most-recent uncorrupted version.
69+
const { container } = await azureClient.viewContainerVersion(id, containerSchema, versions[0], "2");
70+
71+
// We can now start reading the data from the container.
72+
const someData = container.initialObjects.someSharedMap.get("hello");
73+
74+
// With the data extracted, we can inject it into a new uncorrupted container and attach it to start collaborating again.
75+
const { container: newContainer } = await azureClient.createContainer(containerSchema, "2");
76+
newContainer.initialObjects.someSharedMap.set("hello", someData);
77+
const newId = await newContainer.attach();
6478
```
6579

6680
## Key observations
@@ -73,7 +87,7 @@ We aren't recovering (rolling back) existing container. `copyContainer` will giv
7387

7488
New container is initially in `detached` state. We can continue working with detached container, or immediately attach. After calling `attach` we'll get back unique Container ID, representing newly created instance.
7589

76-
## Post-recovery considerations
90+
## Post-recovery considerations
7791

7892
When it comes to building use cases around post-recovery scenarios, here are couple of considerations on what application might want do to get its remote collaborators all working on the same container again.
7993

0 commit comments

Comments
 (0)