fix(server): save snapshot and delete updates in the same transaction (#12856)
close CLOUD-229 #### PR Dependency Tree * **PR #12856** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Refactor** - Improved the internal handling of document updates and snapshots to enhance reliability and maintainability. No changes to user-facing features or functionality. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { Logger } from '@nestjs/common';
|
import { Logger } from '@nestjs/common';
|
||||||
|
import { Transactional } from '@nestjs-cls/transactional';
|
||||||
import {
|
import {
|
||||||
applyUpdate,
|
applyUpdate,
|
||||||
diffUpdate,
|
diffUpdate,
|
||||||
@@ -78,42 +79,55 @@ export abstract class DocStorageAdapter extends Connection {
|
|||||||
const updates = await this.getDocUpdates(spaceId, docId);
|
const updates = await this.getDocUpdates(spaceId, docId);
|
||||||
|
|
||||||
if (updates.length) {
|
if (updates.length) {
|
||||||
this.logger.log(
|
return await this.squashUpdatesToSnapshot(
|
||||||
`Squashing updates, spaceId: ${spaceId}, docId: ${docId}, updates: ${updates.length}`
|
spaceId,
|
||||||
);
|
|
||||||
const { timestamp, bin, editor } = await this.squash(
|
|
||||||
snapshot ? [snapshot, ...updates] : updates
|
|
||||||
);
|
|
||||||
|
|
||||||
const newSnapshot = {
|
|
||||||
spaceId: spaceId,
|
|
||||||
docId,
|
docId,
|
||||||
bin,
|
updates,
|
||||||
timestamp,
|
snapshot
|
||||||
editor,
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const success = await this.setDocSnapshot(newSnapshot);
|
|
||||||
|
|
||||||
// if there is old snapshot, create a new history record
|
|
||||||
if (success && snapshot) {
|
|
||||||
await this.createDocHistory(snapshot);
|
|
||||||
}
|
|
||||||
|
|
||||||
// always mark updates as merged unless throws
|
|
||||||
const count = await this.markUpdatesMerged(spaceId, docId, updates);
|
|
||||||
if (count > 0) {
|
|
||||||
this.logger.log(
|
|
||||||
`Marked ${count} updates as merged, spaceId: ${spaceId}, docId: ${docId}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return newSnapshot;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return snapshot;
|
return snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional()
|
||||||
|
private async squashUpdatesToSnapshot(
|
||||||
|
spaceId: string,
|
||||||
|
docId: string,
|
||||||
|
updates: DocUpdate[],
|
||||||
|
snapshot: DocRecord | null
|
||||||
|
) {
|
||||||
|
this.logger.log(
|
||||||
|
`Squashing updates, spaceId: ${spaceId}, docId: ${docId}, updates: ${updates.length}`
|
||||||
|
);
|
||||||
|
const { timestamp, bin, editor } = await this.squash(
|
||||||
|
snapshot ? [snapshot, ...updates] : updates
|
||||||
|
);
|
||||||
|
|
||||||
|
const newSnapshot: DocRecord = {
|
||||||
|
spaceId,
|
||||||
|
docId,
|
||||||
|
bin,
|
||||||
|
timestamp,
|
||||||
|
editor,
|
||||||
|
};
|
||||||
|
|
||||||
|
const success = await this.setDocSnapshot(newSnapshot);
|
||||||
|
|
||||||
|
// if there is old snapshot, create a new history record
|
||||||
|
if (success && snapshot) {
|
||||||
|
await this.createDocHistory(snapshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
// always mark updates as merged unless throws
|
||||||
|
const count = await this.markUpdatesMerged(spaceId, docId, updates);
|
||||||
|
this.logger.log(
|
||||||
|
`Marked ${count} updates as merged, spaceId: ${spaceId}, docId: ${docId}, timestamp: ${timestamp}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return newSnapshot;
|
||||||
|
}
|
||||||
|
|
||||||
async getDocDiff(
|
async getDocDiff(
|
||||||
spaceId: string,
|
spaceId: string,
|
||||||
docId: string,
|
docId: string,
|
||||||
|
|||||||
Reference in New Issue
Block a user