revert watch computed

This commit is contained in:
tamaina 2023-08-06 16:28:09 +00:00
parent e59ed9008c
commit bd98c3e3fd
1 changed files with 18 additions and 57 deletions

View File

@ -45,7 +45,7 @@ export const driveFileManager = new EntitiyManager<DriveFile>('driveFile');
type OmittedNote = Omit<Note, 'user' | 'renote' | 'reply'>; type OmittedNote = Omit<Note, 'user' | 'renote' | 'reply'>;
type CachedNoteSource = Ref<OmittedNote | null>; type CachedNoteSource = Ref<OmittedNote | null>;
type CachedNote = Ref<Note | null>; type CachedNote = ComputedRef<Note | null>;
type InterruptedCachedNote = Ref<Note | null>; type InterruptedCachedNote = Ref<Note | null>;
export function isRenote(note: Note | OmittedNote | null): boolean { export function isRenote(note: Note | OmittedNote | null): boolean {
@ -78,7 +78,6 @@ export class NoteManager {
* 0 * 0
*/ */
private notesComputed: Map<Note['id'], CachedNote>; private notesComputed: Map<Note['id'], CachedNote>;
private notesComputedUnwatch: Map<Note['id'], () => void>;
private updatedAt: Map<Note['id'], number>; private updatedAt: Map<Note['id'], number>;
private captureing: Map<Note['id'], number>; private captureing: Map<Note['id'], number>;
@ -88,7 +87,6 @@ export class NoteManager {
constructor() { constructor() {
this.notesSource = new Map(); this.notesSource = new Map();
this.notesComputed = new Map(); this.notesComputed = new Map();
this.notesComputedUnwatch = new Map();
this.updatedAt = new Map(); this.updatedAt = new Map();
this.captureing = new Map(); this.captureing = new Map();
this.connection = $i ? useStream() : null; this.connection = $i ? useStream() : null;
@ -152,78 +150,43 @@ export class NoteManager {
public get(id: string): CachedNote { public get(id: string): CachedNote {
if (!this.notesComputed.has(id)) { if (!this.notesComputed.has(id)) {
const note = this.notesSource.get(id); const note = this.notesSource.get(id) ?? this.notesSource.set(id, ref(null)).get(id)!;
if (this.isDebuggerEnabled) console.log('NoteManager: get note (new) start', id, note); this.notesComputed.set(id, computed<Note | null>(() => {
if (this.isDebuggerEnabled) console.log('NoteManager: compute note', id, note.value);
if (!note) { if (!note.value) return null;
throw new Error(`NoteManager: get note (new): ${id} is not found`);
}
if (!note.value) { const user = userLiteManager.get(note.value.userId)!;
if (this.isDebuggerEnabled) console.log('NoteManager: get note (new): deleted', id);
return ref(null);
}
const user = userLiteManager.get(note.value.userId)!; const renote = note.value.renoteId ? this.get(note.value.renoteId) : undefined;
const renote = note.value.renoteId ? this.get(note.value.renoteId) : undefined; // renoteが削除されている場合はCASCADE削除されるためnullを返す
const reply = note.value.replyId ? this.get(note.value.replyId) : undefined;
const files = note.value.fileIds.map(id => driveFileManager.get(id));
const buildNote = (): Note | null => {
if (this.isDebuggerEnabled) console.log('NoteManager: get note (watch): build note', id);
if (note.value == null) return null;
if (renote && !renote.value) return null; if (renote && !renote.value) return null;
const reply = note.value.replyId ? this.get(note.value.replyId) : undefined;
if (reply && !reply.value) return null; if (reply && !reply.value) return null;
const files = note.value.fileIds.map(id => driveFileManager.get(id)?.value);
const result = { const result = {
...note.value, ...note.value,
user: user.value, user: user.value,
renote: renote?.value ?? undefined, renote: renote?.value ?? undefined,
reply: reply?.value ?? undefined, reply: reply?.value ?? undefined,
files: files.filter(file => file).map(file => (file as Ref<DriveFile>).value), files: files.filter(file => file) as DriveFile[],
}; };
if (this.isDebuggerEnabled) console.log('NoteManager: get note (watch): built note (not null)', id, result); if (this.isDebuggerEnabled) console.log('NoteManager: compute note (not null)', id, result);
return result; return result;
};
this.notesComputed.set(id, ref(buildNote()));
this.notesComputedUnwatch.set(id, watch([note, user, renote, reply, ...files], () => {
if (this.isDebuggerEnabled) console.log('NoteManager: note updated', id);
const cached = this.notesComputed.get(id);
if (cached) {
if (this.isDebuggerEnabled) console.log('NoteManager: note computed watcher dispatch (cached)', id);
cached.value = buildNote();
} else {
if (this.isDebuggerEnabled) console.log('NoteManager: note computed watcher dispatch (not cached)', id);
this.deleteComputed(id);
}
})); }));
if (this.isDebuggerEnabled) console.log('NoteManager: get note (new)', id, this.notesComputed.get(id));
if (this.isDebuggerEnabled) console.log('NoteManager: get note (new) result', id, this.notesComputed.get(id), this.notesComputedUnwatch.get(id));
} else { } else {
if (this.isDebuggerEnabled) console.log('NoteManager: get note (cached)', id, this.notesComputed.get(id), this.notesSource.get(id)?.value); if (this.isDebuggerEnabled) console.log('NoteManager: get note (cached)', id, this.notesComputed.get(id), this.notesSource.get(id)?.value);
} }
return this.notesComputed.get(id)!; return this.notesComputed.get(id)!;
} }
public deleteComputed(id: string): void {
const unwatch = this.notesComputedUnwatch.get(id);
if (this.isDebuggerEnabled) {
const cached = this.notesComputed.get(id);
console.log('NoteManager: deleteComputed', id, { cached, unwatch });
}
this.notesComputed.delete(id);
if (unwatch) {
unwatch();
this.notesComputedUnwatch.delete(id);
}
}
/** /**
* Interruptorを適用する * Interruptorを適用する
* *
@ -336,7 +299,7 @@ export class NoteManager {
if (this.isDebuggerEnabled) console.log('NoteManager: onStreamNoteUpdated (not found)', id, note?.value); if (this.isDebuggerEnabled) console.log('NoteManager: onStreamNoteUpdated (not found)', id, note?.value);
this.connection?.send('un', { id }); this.connection?.send('un', { id });
this.captureing.delete(id); this.captureing.delete(id);
this.deleteComputed(id); this.notesComputed.delete(id);
this.updatedAt.delete(id); this.updatedAt.delete(id);
return; return;
} else { } else {
@ -402,7 +365,7 @@ export class NoteManager {
note.value = null; note.value = null;
this.connection?.send('un', { id }); this.connection?.send('un', { id });
this.captureing.delete(id); this.captureing.delete(id);
this.deleteComputed(id); this.notesComputed.delete(id);
this.updatedAt.delete(id); this.updatedAt.delete(id);
break; break;
} }
@ -453,9 +416,7 @@ export class NoteManager {
this.captureing.delete(id); this.captureing.delete(id);
// キャプチャが終わったらcomputedキャッシュも消してしまう // キャプチャが終わったらcomputedキャッシュも消してしまう
if (!noDeletion) { if (!noDeletion) this.notesComputed.delete(id);
this.deleteComputed(id);
}
} }
/** /**