mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) add explicit doc and inventory creation step
Summary: Currently, if a document is created by importing a file, inventory creation is a little haphazard - it works, but triggers a "surprise" message. This diff makes initialization of inventory explicit, so that surprise messages shouldn't happen during document creation. Test Plan: manual Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2696
This commit is contained in:
parent
24e76b4abc
commit
d5b00f5169
@ -300,6 +300,7 @@ export class ActiveDoc extends EventEmitter {
|
||||
@ActiveDoc.keepDocOpen
|
||||
public async createDoc(docSession: OptDocSession): Promise<ActiveDoc> {
|
||||
this.logDebug(docSession, "createDoc");
|
||||
await this._docManager.storageManager.prepareToCreateDoc(this.docName);
|
||||
await this.docStorage.createFile();
|
||||
await this._rawPyCall('load_empty');
|
||||
const timezone = docSession.browserSettings ? docSession.browserSettings.timezone : DEFAULT_TIMEZONE;
|
||||
|
@ -110,6 +110,17 @@ export class DocSnapshotInventory implements IInventory {
|
||||
constructor(private _doc: ExternalStorage, private _meta: ExternalStorage,
|
||||
private _getFilename: (key: string) => Promise<string>) {}
|
||||
|
||||
/**
|
||||
* Start keeping inventory for a new document.
|
||||
*/
|
||||
public async create(key: string) {
|
||||
await this._mutex.runExclusive(key, async() => {
|
||||
const fname = await this._getFilename(key);
|
||||
await this._saveToFile(fname, []);
|
||||
this._needFlush.add(key);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new snapshot of a document to the existing inventory. A prevSnapshotId may
|
||||
* be supplied as a cross-check. It will be matched against the most recent
|
||||
@ -126,7 +137,7 @@ export class DocSnapshotInventory implements IInventory {
|
||||
await this._mutex.runExclusive(key, async() => {
|
||||
const snapshots = await this._getSnapshots(key, prevSnapshotId);
|
||||
// Could be already added if reconstruction happened.
|
||||
if (snapshots[0].snapshotId === snapshot.snapshotId) { return; }
|
||||
if (snapshots[0] && snapshots[0].snapshotId === snapshot.snapshotId) { return; }
|
||||
this._normalizeMetadata(snapshot);
|
||||
snapshots.unshift(snapshot);
|
||||
const fname = await this._getFilename(key);
|
||||
|
@ -87,6 +87,10 @@ export class DocStorageManager implements IDocStorageManager {
|
||||
*/
|
||||
public async prepareLocalDoc(docName: string, docSession: OptDocSession): Promise<boolean> { return false; }
|
||||
|
||||
public async prepareToCreateDoc(docName: string): Promise<void> {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise for the list of docNames to show in the doc list. For the file-based
|
||||
* storage, this will include all .grist files under the docsRoot.
|
||||
@ -212,7 +216,7 @@ export class DocStorageManager implements IDocStorageManager {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
public addToStorage(id: string): void {
|
||||
public async addToStorage(id: string): Promise<void> {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,8 @@ export class HostedStorageManager implements IDocStorageManager {
|
||||
*/
|
||||
public async addToStorage(docId: string) {
|
||||
if (this._disableS3) { return; }
|
||||
await this._ext.upload(docId, this.getPath(docId));
|
||||
this._uploads.addOperation(docId);
|
||||
await this._uploads.expediteOperationAndWait(docId);
|
||||
}
|
||||
|
||||
public getPath(docName: string): string {
|
||||
@ -234,6 +235,13 @@ export class HostedStorageManager implements IDocStorageManager {
|
||||
}
|
||||
}
|
||||
|
||||
public async prepareToCreateDoc(docName: string): Promise<void> {
|
||||
if (this._inventory) {
|
||||
await this._inventory.create(docName);
|
||||
this._onInventoryChange(docName);
|
||||
}
|
||||
}
|
||||
|
||||
// Gets a copy of the document, eg. for downloading. Returns full file path.
|
||||
// Copy won't change if edits are made to the document. It is caller's responsibility
|
||||
// to delete the result.
|
||||
@ -656,10 +664,7 @@ export class HostedStorageManager implements IDocStorageManager {
|
||||
metadata
|
||||
}
|
||||
await this._inventory.add(docId, snapshot, prevSnapshotId);
|
||||
const scheduled = this._pruner.requestPrune(docId);
|
||||
if (!scheduled) {
|
||||
await this._inventory.flush(docId);
|
||||
}
|
||||
await this._onInventoryChange(docId);
|
||||
} finally {
|
||||
// Clean up backup.
|
||||
// NOTE: fse.remove succeeds also when the file does not exist.
|
||||
@ -667,6 +672,14 @@ export class HostedStorageManager implements IDocStorageManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure inventory change is followed up on.
|
||||
private async _onInventoryChange(docId: string) {
|
||||
const scheduled = this._pruner.requestPrune(docId);
|
||||
if (!scheduled) {
|
||||
await this._inventory.flush(docId);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract actionHash, actionNum, and timezone from a document backup.
|
||||
private async _getDocMetadata(fname: string): Promise<{[key: string]: string}> {
|
||||
const result: Record<string, string> = {};
|
||||
|
@ -12,6 +12,7 @@ export interface IDocStorageManager {
|
||||
// In the current implementation, it is called in the context of an
|
||||
// AsyncCreate[docName].
|
||||
prepareLocalDoc(docName: string, docSession: OptDocSession): Promise<boolean>;
|
||||
prepareToCreateDoc(docName: string): Promise<void>;
|
||||
|
||||
listDocs(): Promise<DocEntry[]>;
|
||||
deleteDoc(docName: string, deletePermanently?: boolean): Promise<void>;
|
||||
@ -24,7 +25,7 @@ export interface IDocStorageManager {
|
||||
// If reason is set to 'edit' the user-facing timestamp on the document should be updated.
|
||||
markAsChanged(docName: string, reason?: 'edit'): void;
|
||||
testReopenStorage(): void; // restart storage during tests
|
||||
addToStorage(docName: string): void; // add a new local document to storage
|
||||
addToStorage(docName: string): Promise<void>; // add a new local document to storage
|
||||
prepareToCloseStorage(): void; // speed up sync with remote store
|
||||
getCopy(docName: string): Promise<string>; // get an immutable copy of a document
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user