|
| 1 | +--- |
| 2 | +author: hickeys |
| 3 | +description: Learn how to recover container data |
| 4 | +title: Recovering Fluid data |
| 5 | +ms.author: hickeys |
| 6 | +ms.date: 06/22/2022 |
| 7 | +ms.service: azure-fluid |
| 8 | +ms.topic: reference |
| 9 | +--- |
| 10 | + |
| 11 | +# Recovering container data |
| 12 | + |
| 13 | +In this scenario, we'll be exploring data recovery. We consider data to be corrupted when container reaches an invalid state where it can't process further user actions. The outcome of corrupted state is container being unexpectedly closed. Often it's transient state, and upon reopening, the container may behave as expected. In a situation where a container fails to load even after multiple retries, we offer APIs and flows you can use to recover your data, as described below. |
| 14 | + |
| 15 | +## How Fluid Framework and Azure Fluid Relay save state |
| 16 | + |
| 17 | +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. |
| 18 | + |
| 19 | +## Azure client APIs |
| 20 | + |
| 21 | +We've added following methods to AzureClient that will enable developers to recover data from corrupted containers. |
| 22 | + |
| 23 | +[`getContainerVersions(ID, options)`](https://fluidframework.com/docs/apis/azure-client/azureclient/#azure-client-azureclient-getcontainerversions-Method) |
| 24 | + |
| 25 | +`getContainerVersions` allows developers to view the previously generated versions of the container. |
| 26 | + |
| 27 | +[copyContainer(ID, containerSchema)](https://fluidframework.com/docs/apis/azure-client/azureclient/#azure-client-azureclient-copycontainer-Method) |
| 28 | + |
| 29 | +`copyContainer` allows developers to generate a new detached container from a specific version of another container. |
| 30 | + |
| 31 | +## Example recovery flow |
| 32 | + |
| 33 | +```typescript |
| 34 | + |
| 35 | +async function recoverDoc( |
| 36 | + client: AzureClient, |
| 37 | + orgContainerId: string, |
| 38 | + containerScema: ContainerSchema, |
| 39 | +): Promise<string> { |
| 40 | + /* Collect doc versions */ |
| 41 | + let versions: AzureContainerVersion[] = []; |
| 42 | + try { |
| 43 | + versions = await client.getContainerVersions(orgContainerId); |
| 44 | + } catch (e) { |
| 45 | + return Promise.reject(new Error("Unable to get container versions.")); |
| 46 | + } |
| 47 | + |
| 48 | + for (const version of versions) { |
| 49 | + /* Versions are returned in chronological order. |
| 50 | + Attempt to copy doc from next available version */ |
| 51 | + try { |
| 52 | + const { container: newContainer } = await client.copyContainer( |
| 53 | + orgContainerId, |
| 54 | + containerSchema, |
| 55 | + version, |
| 56 | + ); |
| 57 | + return await newContainer.attach(); |
| 58 | + } catch (e) { |
| 59 | + // Error. Keep going. |
| 60 | + } |
| 61 | + } |
| 62 | + |
| 63 | + return Promise.reject(new Error("Could not recreate document")); |
| 64 | +} |
| 65 | + |
| 66 | +``` |
| 67 | + |
| 68 | +## Key observations |
| 69 | + |
| 70 | +### We're creating a new Container |
| 71 | + |
| 72 | +We aren't recovering (rolling back) existing container. `copyContainer` will give us new instance, with data being copied from the original container. In this process, old container isn't deleted. |
| 73 | + |
| 74 | +### New Container is detached |
| 75 | + |
| 76 | + 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. |
0 commit comments