Fix missed events

pull/929/head
Zef Hemel 2024-07-10 11:32:07 +02:00
parent c7f5645075
commit 3e94389c1e
2 changed files with 50 additions and 3 deletions

View File

@ -18,12 +18,14 @@ export class EventedSpacePrimitives implements SpacePrimitives {
// 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.
operationInProgress = false; operationInProgress = false;
initialFileListLoad = true; initialFileListLoad: boolean;
public enabled = true;
spaceSnapshot: Record<string, number> = {};
constructor( constructor(
private wrapped: SpacePrimitives, private wrapped: SpacePrimitives,
private eventHook: EventHook, private eventHook: EventHook,
private spaceSnapshot: Record<string, number> = {},
) { ) {
// Translate file change events for attachments into attachment:index events // Translate file change events for attachments into attachment:index events
this.eventHook.addLocalListener( this.eventHook.addLocalListener(
@ -37,6 +39,8 @@ export class EventedSpacePrimitives implements SpacePrimitives {
} }
}, },
); );
this.initialFileListLoad = Object.keys(this.spaceSnapshot).length === 0;
// console.log("Loaded space snapshot", spaceSnapshot);
} }
dispatchEvent(name: string, ...args: any[]): Promise<any[]> { dispatchEvent(name: string, ...args: any[]): Promise<any[]> {
@ -44,6 +48,9 @@ export class EventedSpacePrimitives implements SpacePrimitives {
} }
async fetchFileList(): Promise<FileMeta[]> { async fetchFileList(): Promise<FileMeta[]> {
if (!this.enabled) {
return this.wrapped.fetchFileList();
}
if (this.operationInProgress) { 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.
@ -52,6 +59,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
); );
return this.wrapped.fetchFileList(); return this.wrapped.fetchFileList();
} }
// console.log("Fetching file list");
// Fetching mutex // Fetching mutex
this.operationInProgress = true; this.operationInProgress = true;
try { try {
@ -77,6 +85,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
oldHash !== newHash oldHash !== newHash
) )
) { ) {
console.log("Detected file change", meta.name, oldHash, newHash);
await this.dispatchEvent( await this.dispatchEvent(
"file:changed", "file:changed",
meta.name, meta.name,
@ -100,6 +109,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
} }
await this.dispatchEvent("file:listed", newFileList); await this.dispatchEvent("file:listed", newFileList);
await this.dispatchEvent("file:spaceSnapshotted", this.spaceSnapshot);
this.initialFileListLoad = false; this.initialFileListLoad = false;
return newFileList; return newFileList;
} finally { } finally {
@ -110,6 +120,9 @@ export class EventedSpacePrimitives implements SpacePrimitives {
async readFile( async readFile(
name: string, name: string,
): Promise<{ data: Uint8Array; meta: FileMeta }> { ): Promise<{ data: Uint8Array; meta: FileMeta }> {
if (!this.enabled) {
return this.wrapped.readFile(name);
}
try { try {
// Fetching mutex // Fetching mutex
const wasFetching = this.operationInProgress; const wasFetching = this.operationInProgress;
@ -133,6 +146,9 @@ export class EventedSpacePrimitives implements SpacePrimitives {
selfUpdate?: boolean, selfUpdate?: boolean,
meta?: FileMeta, meta?: FileMeta,
): Promise<FileMeta> { ): Promise<FileMeta> {
if (!this.enabled) {
return this.wrapped.writeFile(name, data, selfUpdate, meta);
}
try { try {
this.operationInProgress = true; this.operationInProgress = true;
const newMeta = await this.wrapped.writeFile( const newMeta = await this.wrapped.writeFile(
@ -163,6 +179,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
text, text,
}); });
} }
await this.dispatchEvent("file:spaceSnapshotted", this.spaceSnapshot);
return newMeta; return newMeta;
} finally { } finally {
this.operationInProgress = false; this.operationInProgress = false;
@ -180,6 +197,9 @@ export class EventedSpacePrimitives implements SpacePrimitives {
} }
async getFileMeta(name: string): Promise<FileMeta> { async getFileMeta(name: string): Promise<FileMeta> {
if (!this.enabled) {
return this.wrapped.getFileMeta(name);
}
try { try {
const wasFetching = this.operationInProgress; const wasFetching = this.operationInProgress;
this.operationInProgress = true; this.operationInProgress = true;
@ -204,6 +224,9 @@ export class EventedSpacePrimitives implements SpacePrimitives {
} }
async deleteFile(name: string): Promise<void> { async deleteFile(name: string): Promise<void> {
if (!this.enabled) {
return this.wrapped.deleteFile(name);
}
try { try {
this.operationInProgress = true; this.operationInProgress = true;
if (name.endsWith(".md")) { if (name.endsWith(".md")) {
@ -214,6 +237,7 @@ export class EventedSpacePrimitives implements SpacePrimitives {
await this.wrapped.deleteFile(name); await this.wrapped.deleteFile(name);
delete this.spaceSnapshot[name]; delete this.spaceSnapshot[name];
await this.dispatchEvent("file:deleted", name); await this.dispatchEvent("file:deleted", name);
await this.dispatchEvent("file:spaceSnapshotted", this.spaceSnapshot);
} finally { } finally {
this.operationInProgress = false; this.operationInProgress = false;
} }

View File

@ -97,13 +97,31 @@ export class ServerSystem extends CommonSystem {
this.system.addHook(codeWidgetHook); this.system.addHook(codeWidgetHook);
this.spacePrimitives = new EventedSpacePrimitives( // Look up spaceCache meta data in KV
const spaceCache = (await this.ds.get(["$spaceCache"])) || {};
const eventedSpacePrimitives = new EventedSpacePrimitives(
new PlugSpacePrimitives( new PlugSpacePrimitives(
this.spacePrimitives, this.spacePrimitives,
plugNamespaceHook, plugNamespaceHook,
), ),
this.eventHook, this.eventHook,
spaceCache,
); );
// Disable events until everything is set up
eventedSpacePrimitives.enabled = false;
this.spacePrimitives = eventedSpacePrimitives;
this.eventHook.addLocalListener(
"file:spaceSnapshotted",
(snapshot: Record<string, any>) => {
console.log("Space snapshot updated");
return this.ds.set(["$spaceCache"], snapshot);
},
);
const space = new Space(this.spacePrimitives, this.eventHook); const space = new Space(this.spacePrimitives, this.eventHook);
// Add syscalls // Add syscalls
@ -187,6 +205,11 @@ export class ServerSystem extends CommonSystem {
}, },
); );
// All setup, enable eventing
eventedSpacePrimitives.enabled = true;
space.updatePageList().catch(console.error);
// Ensure a valid index // Ensure a valid index
const indexPromise = ensureSpaceIndex(this.ds, this.system); const indexPromise = ensureSpaceIndex(this.ds, this.system);
if (awaitIndex) { if (awaitIndex) {