Improve network usage for small text changes (#166)
This commit is contained in:
parent
1da17c462e
commit
be1635c26e
20 changed files with 697 additions and 62 deletions
|
|
@ -17,6 +17,7 @@ import { createPromise } from "../utils/create-promise";
|
|||
import { SyncResetError } from "../services/sync-reset-error";
|
||||
import { Locks } from "../utils/locks";
|
||||
import type { DocumentVersionWithoutContent } from "../services/types/DocumentVersionWithoutContent";
|
||||
import type { FixedSizeDocumentCache } from "../utils/fix-sized-cache";
|
||||
|
||||
export class Syncer {
|
||||
private readonly remoteDocumentsLock: Locks<DocumentId>;
|
||||
|
|
@ -33,7 +34,8 @@ export class Syncer {
|
|||
settings: Settings,
|
||||
private readonly syncService: SyncService,
|
||||
private readonly operations: FileOperations,
|
||||
private readonly internalSyncer: UnrestrictedSyncer
|
||||
private readonly internalSyncer: UnrestrictedSyncer,
|
||||
private readonly contentCache: FixedSizeDocumentCache
|
||||
) {
|
||||
this.syncQueue = new PQueue({
|
||||
concurrency: settings.getSettings().syncConcurrency
|
||||
|
|
@ -250,6 +252,7 @@ export class Syncer {
|
|||
|
||||
public async reset(): Promise<void> {
|
||||
await this.waitUntilFinished();
|
||||
this.contentCache.clear();
|
||||
}
|
||||
|
||||
public async syncRemotelyUpdatedFile(
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import type {
|
|||
RelativePath
|
||||
} from "../persistence/database";
|
||||
|
||||
import { diff } from "reconcile-text";
|
||||
import type { SyncService } from "../services/sync-service";
|
||||
import type { Logger } from "../tracing/logger";
|
||||
import type {
|
||||
|
|
@ -27,6 +28,9 @@ import { globsToRegexes } from "../utils/globs-to-regexes";
|
|||
import type { DocumentVersion } from "../services/types/DocumentVersion";
|
||||
import type { DocumentUpdateResponse } from "../services/types/DocumentUpdateResponse";
|
||||
import type { DocumentVersionWithoutContent } from "../services/types/DocumentVersionWithoutContent";
|
||||
import type { FixedSizeDocumentCache } from "../utils/fix-sized-cache";
|
||||
import { isFileTypeMergable } from "../utils/is-file-type-mergable";
|
||||
import { isBinary } from "../utils/is-binary";
|
||||
|
||||
export class UnrestrictedSyncer {
|
||||
private ignorePatterns: RegExp[];
|
||||
|
|
@ -37,7 +41,8 @@ export class UnrestrictedSyncer {
|
|||
private readonly settings: Settings,
|
||||
private readonly syncService: SyncService,
|
||||
private readonly operations: FileOperations,
|
||||
private readonly history: SyncHistory
|
||||
private readonly history: SyncHistory,
|
||||
private readonly contentCache: FixedSizeDocumentCache
|
||||
) {
|
||||
this.ignorePatterns = globsToRegexes(
|
||||
this.settings.getSettings().ignorePatterns,
|
||||
|
|
@ -87,8 +92,12 @@ export class UnrestrictedSyncer {
|
|||
},
|
||||
document
|
||||
);
|
||||
|
||||
this.database.addSeenUpdateId(response.vaultUpdateId);
|
||||
this.updateCache(
|
||||
response.vaultUpdateId,
|
||||
contentBytes,
|
||||
response.relativePath
|
||||
);
|
||||
|
||||
this.history.addHistoryEntry({
|
||||
status: SyncStatus.SUCCESS,
|
||||
|
|
@ -178,12 +187,32 @@ export class UnrestrictedSyncer {
|
|||
undefined;
|
||||
|
||||
if (areThereLocalChanges) {
|
||||
response = await this.syncService.put({
|
||||
documentId: document.documentId,
|
||||
parentVersionId: document.metadata.parentVersionId,
|
||||
relativePath: document.relativePath,
|
||||
contentBytes
|
||||
});
|
||||
const isText =
|
||||
!isBinary(contentBytes) &&
|
||||
isFileTypeMergable(document.relativePath);
|
||||
const cachedVersion = this.contentCache.get(
|
||||
document.metadata.parentVersionId
|
||||
);
|
||||
|
||||
response =
|
||||
isText && cachedVersion !== undefined
|
||||
? await this.syncService.putText({
|
||||
documentId: document.documentId,
|
||||
parentVersionId:
|
||||
document.metadata.parentVersionId,
|
||||
relativePath: document.relativePath,
|
||||
content: diff(
|
||||
new TextDecoder().decode(cachedVersion),
|
||||
new TextDecoder().decode(contentBytes)
|
||||
)
|
||||
})
|
||||
: await this.syncService.putBinary({
|
||||
documentId: document.documentId,
|
||||
parentVersionId:
|
||||
document.metadata.parentVersionId,
|
||||
relativePath: document.relativePath,
|
||||
contentBytes
|
||||
});
|
||||
} else {
|
||||
if (!force) {
|
||||
this.logger.debug(
|
||||
|
|
@ -274,12 +303,16 @@ export class UnrestrictedSyncer {
|
|||
},
|
||||
document
|
||||
);
|
||||
|
||||
await this.operations.write(
|
||||
actualPath,
|
||||
contentBytes,
|
||||
responseBytes
|
||||
);
|
||||
this.updateCache(
|
||||
response.vaultUpdateId,
|
||||
responseBytes,
|
||||
actualPath
|
||||
);
|
||||
|
||||
if (!force) {
|
||||
this.history.addHistoryEntry({
|
||||
|
|
@ -297,6 +330,11 @@ export class UnrestrictedSyncer {
|
|||
},
|
||||
document
|
||||
);
|
||||
this.updateCache(
|
||||
response.vaultUpdateId,
|
||||
contentBytes,
|
||||
actualPath
|
||||
);
|
||||
}
|
||||
|
||||
this.database.addSeenUpdateId(response.vaultUpdateId);
|
||||
|
|
@ -423,6 +461,11 @@ export class UnrestrictedSyncer {
|
|||
remoteVersion.relativePath,
|
||||
contentBytes
|
||||
);
|
||||
this.updateCache(
|
||||
remoteVersion.vaultUpdateId,
|
||||
contentBytes,
|
||||
remoteVersion.relativePath
|
||||
);
|
||||
|
||||
resolve();
|
||||
this.database.removeDocumentPromise(promise);
|
||||
|
|
@ -513,4 +556,14 @@ export class UnrestrictedSyncer {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
private updateCache(
|
||||
updateId: number,
|
||||
contentBytes: Uint8Array,
|
||||
filePath: RelativePath
|
||||
): void {
|
||||
if (isFileTypeMergable(filePath) && !isBinary(contentBytes)) {
|
||||
this.contentCache.put(updateId, contentBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue