More reload fix attempts
parent
2800185893
commit
ca5b6803eb
|
@ -15,7 +15,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
// Various operations may be going on at the same time, and we don't want to trigger events unnessarily.
|
// Various operations may be going on at the same time, and we don't want to trigger events unnessarily.
|
||||||
// Therefore we use this variable to track if any operation is in flight, and if so, we skip event triggering.
|
// Therefore we use this variable to track if any operation is in flight, and if so, we skip event triggering.
|
||||||
// This is ok, because any event will be picked up in a following iteration.
|
// This is ok, because any event will be picked up in a following iteration.
|
||||||
alreadyFetching = false;
|
operationInProgress = false;
|
||||||
|
|
||||||
initialFileListLoad = true;
|
initialFileListLoad = true;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchFileList(): Promise<FileMeta[]> {
|
async fetchFileList(): Promise<FileMeta[]> {
|
||||||
if (this.alreadyFetching) {
|
if (this.operationInProgress) {
|
||||||
// Some other operation (read, write, list, meta) is already going on
|
// Some other operation (read, write, list, meta) is already going on
|
||||||
// this will likely trigger events, so let's not worry about any of that and avoid race condition and inconsistent data.
|
// this will likely trigger events, so let's not worry about any of that and avoid race condition and inconsistent data.
|
||||||
console.info(
|
console.info(
|
||||||
|
@ -40,10 +40,12 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
return this.wrapped.fetchFileList();
|
return this.wrapped.fetchFileList();
|
||||||
}
|
}
|
||||||
// Fetching mutex
|
// Fetching mutex
|
||||||
this.alreadyFetching = true;
|
this.operationInProgress = true;
|
||||||
// Fetch the list
|
|
||||||
const newFileList = await this.wrapped.fetchFileList();
|
|
||||||
try {
|
try {
|
||||||
|
// Fetch the list
|
||||||
|
const newFileList = await this.wrapped.fetchFileList();
|
||||||
|
|
||||||
|
// Now we have the list, let's compare it to the snapshot and trigger events appropriately
|
||||||
const deletedFiles = new Set<string>(Object.keys(this.spaceSnapshot));
|
const deletedFiles = new Set<string>(Object.keys(this.spaceSnapshot));
|
||||||
for (const meta of newFileList) {
|
for (const meta of newFileList) {
|
||||||
const oldHash = this.spaceSnapshot[meta.name];
|
const oldHash = this.spaceSnapshot[meta.name];
|
||||||
|
@ -88,7 +90,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
this.initialFileListLoad = false;
|
this.initialFileListLoad = false;
|
||||||
return newFileList;
|
return newFileList;
|
||||||
} finally {
|
} finally {
|
||||||
this.alreadyFetching = false;
|
this.operationInProgress = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,8 +99,8 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
): Promise<{ data: Uint8Array; meta: FileMeta }> {
|
): Promise<{ data: Uint8Array; meta: FileMeta }> {
|
||||||
try {
|
try {
|
||||||
// Fetching mutex
|
// Fetching mutex
|
||||||
const wasFetching = this.alreadyFetching;
|
const wasFetching = this.operationInProgress;
|
||||||
this.alreadyFetching = true;
|
this.operationInProgress = true;
|
||||||
|
|
||||||
// Fetch file
|
// Fetch file
|
||||||
const data = await this.wrapped.readFile(name);
|
const data = await this.wrapped.readFile(name);
|
||||||
|
@ -107,7 +109,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
} finally {
|
} finally {
|
||||||
this.alreadyFetching = false;
|
this.operationInProgress = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,15 +120,14 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
meta?: FileMeta,
|
meta?: FileMeta,
|
||||||
): Promise<FileMeta> {
|
): Promise<FileMeta> {
|
||||||
try {
|
try {
|
||||||
const wasFetching = this.alreadyFetching;
|
this.operationInProgress = true;
|
||||||
this.alreadyFetching = true;
|
|
||||||
const newMeta = await this.wrapped.writeFile(
|
const newMeta = await this.wrapped.writeFile(
|
||||||
name,
|
name,
|
||||||
data,
|
data,
|
||||||
selfUpdate,
|
selfUpdate,
|
||||||
meta,
|
meta,
|
||||||
);
|
);
|
||||||
if (!selfUpdate && !wasFetching) {
|
if (!selfUpdate) {
|
||||||
await this.dispatchEvent(
|
await this.dispatchEvent(
|
||||||
"file:changed",
|
"file:changed",
|
||||||
name,
|
name,
|
||||||
|
@ -135,9 +136,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
newMeta.lastModified,
|
newMeta.lastModified,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!wasFetching) {
|
this.spaceSnapshot[name] = newMeta.lastModified;
|
||||||
this.spaceSnapshot[name] = newMeta.lastModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name.endsWith(".md")) {
|
if (name.endsWith(".md")) {
|
||||||
// Let's trigger some page-specific events
|
// Let's trigger some page-specific events
|
||||||
|
@ -154,7 +153,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
}
|
}
|
||||||
return newMeta;
|
return newMeta;
|
||||||
} finally {
|
} finally {
|
||||||
this.alreadyFetching = false;
|
this.operationInProgress = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,8 +169,8 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
|
|
||||||
async getFileMeta(name: string): Promise<FileMeta> {
|
async getFileMeta(name: string): Promise<FileMeta> {
|
||||||
try {
|
try {
|
||||||
const wasFetching = this.alreadyFetching;
|
const wasFetching = this.operationInProgress;
|
||||||
this.alreadyFetching = true;
|
this.operationInProgress = true;
|
||||||
const newMeta = await this.wrapped.getFileMeta(name);
|
const newMeta = await this.wrapped.getFileMeta(name);
|
||||||
if (!wasFetching) {
|
if (!wasFetching) {
|
||||||
this.triggerEventsAndCache(name, newMeta.lastModified);
|
this.triggerEventsAndCache(name, newMeta.lastModified);
|
||||||
|
@ -188,13 +187,13 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
this.alreadyFetching = false;
|
this.operationInProgress = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteFile(name: string): Promise<void> {
|
async deleteFile(name: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
this.alreadyFetching = true;
|
this.operationInProgress = true;
|
||||||
if (name.endsWith(".md")) {
|
if (name.endsWith(".md")) {
|
||||||
const pageName = name.substring(0, name.length - 3);
|
const pageName = name.substring(0, name.length - 3);
|
||||||
await this.dispatchEvent("page:deleted", pageName);
|
await this.dispatchEvent("page:deleted", pageName);
|
||||||
|
@ -204,7 +203,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
|
||||||
delete this.spaceSnapshot[name];
|
delete this.spaceSnapshot[name];
|
||||||
await this.dispatchEvent("file:deleted", name);
|
await this.dispatchEvent("file:deleted", name);
|
||||||
} finally {
|
} finally {
|
||||||
this.alreadyFetching = false;
|
this.operationInProgress = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -591,17 +591,25 @@ export class Client {
|
||||||
this.eventHook,
|
this.eventHook,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let lastSaveTimestamp: number | undefined;
|
||||||
|
|
||||||
|
this.eventHook.addLocalListener("editor:pageSaving", () => {
|
||||||
|
lastSaveTimestamp = Date.now();
|
||||||
|
});
|
||||||
|
|
||||||
this.eventHook.addLocalListener(
|
this.eventHook.addLocalListener(
|
||||||
"file:changed",
|
"file:changed",
|
||||||
(
|
(
|
||||||
path: string,
|
path: string,
|
||||||
_localChange?: boolean,
|
_localChange: boolean,
|
||||||
oldHash?: number,
|
oldHash: number,
|
||||||
newHash?: number,
|
newHash: number,
|
||||||
) => {
|
) => {
|
||||||
// Only reload when watching the current page (to avoid reloading when switching pages)
|
// Only reload when watching the current page (to avoid reloading when switching pages)
|
||||||
if (
|
if (
|
||||||
this.space.watchInterval && `${this.currentPage}.md` === path
|
this.space.watchInterval && `${this.currentPage}.md` === path &&
|
||||||
|
// Avoid reloading if the page was just saved (5s window)
|
||||||
|
(!lastSaveTimestamp || (lastSaveTimestamp < Date.now() - 5000))
|
||||||
) {
|
) {
|
||||||
console.log(
|
console.log(
|
||||||
"Page changed elsewhere, reloading. Old hash",
|
"Page changed elsewhere, reloading. Old hash",
|
||||||
|
@ -609,6 +617,12 @@ export class Client {
|
||||||
"new hash",
|
"new hash",
|
||||||
newHash,
|
newHash,
|
||||||
);
|
);
|
||||||
|
console.log(
|
||||||
|
"Last save timestamp",
|
||||||
|
lastSaveTimestamp,
|
||||||
|
"now",
|
||||||
|
Date.now(),
|
||||||
|
);
|
||||||
this.flashNotification("Page changed elsewhere, reloading");
|
this.flashNotification("Page changed elsewhere, reloading");
|
||||||
this.reloadPage();
|
this.reloadPage();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue