From df0a1d67949ccaca5f17a0a298581d7f8ac22ab1 Mon Sep 17 00:00:00 2001 From: Pierre Date: Sat, 17 Jan 2026 19:59:15 +0100 Subject: [PATCH] bugfix meta-fuse --- packages/meta-fuse-core/src/index.ts | 50 +++++++++++++++++++ .../src/vfs/VirtualFileSystem.ts | 44 ++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/packages/meta-fuse-core/src/index.ts b/packages/meta-fuse-core/src/index.ts index 37eaf2c..cda1fd5 100644 --- a/packages/meta-fuse-core/src/index.ts +++ b/packages/meta-fuse-core/src/index.ts @@ -17,6 +17,23 @@ const logger = new Logger({ name: 'meta-fuse' }); // Pub/sub channel for batched updates from meta-sort const UPDATE_CHANNEL = 'meta-sort:file:batch'; +// Pub/sub channel for scan reset notification from meta-sort +const RESET_CHANNEL = 'meta-sort:scan:reset'; + +// Pub/sub channel for plugin completion events from meta-sort +const PLUGIN_COMPLETE_CHANNEL = 'meta-sort:plugin:complete'; + +// Plugins that provide metadata needed for VFS virtual paths +// When these complete, we should update the VFS entry for that file +const VFS_RELEVANT_PLUGINS = new Set(['filename-parser', 'tmdb', 'jellyfin-nfo']); + +interface PluginCompleteMessage { + fileHash: string; + pluginId: string; + filePath: string; + timestamp: number; +} + interface BatchUpdateMessage { timestamp: number; changes: Array<{ @@ -132,6 +149,39 @@ async function main(): Promise { } }); + // Subscribe to scan reset events from meta-sort + logger.info(`Subscribing to ${RESET_CHANNEL}...`); + await redisClient.subscribe(RESET_CHANNEL, async (message: string) => { + try { + const event = JSON.parse(message); + logger.info(`Received scan reset event: ${event.action}`); + + // Reset VFS for fresh scan - will be rebuilt incrementally + vfs!.reset(); + + logger.info('VFS reset complete, awaiting new file updates from meta-sort'); + } catch (error: any) { + logger.error(`Error processing reset event: ${error.message}`); + } + }); + + // Subscribe to plugin completion events from meta-sort + // When relevant plugins complete (filename-parser, tmdb, etc.), update VFS + logger.info(`Subscribing to ${PLUGIN_COMPLETE_CHANNEL}...`); + await redisClient.subscribe(PLUGIN_COMPLETE_CHANNEL, async (message: string) => { + try { + const event: PluginCompleteMessage = JSON.parse(message); + + // Only process plugins that provide VFS-relevant metadata + if (VFS_RELEVANT_PLUGINS.has(event.pluginId)) { + logger.debug(`Plugin ${event.pluginId} completed for ${event.fileHash}, updating VFS`); + await vfs!.onFileUpdate(event.fileHash, 'update'); + } + } catch (error: any) { + logger.error(`Error processing plugin complete event: ${error.message}`); + } + }); + // Initialize API server (with kvManager for service discovery) apiServer = new APIServer(vfs, { port: config.apiPort, diff --git a/packages/meta-fuse-core/src/vfs/VirtualFileSystem.ts b/packages/meta-fuse-core/src/vfs/VirtualFileSystem.ts index bfc58a4..3119899 100644 --- a/packages/meta-fuse-core/src/vfs/VirtualFileSystem.ts +++ b/packages/meta-fuse-core/src/vfs/VirtualFileSystem.ts @@ -150,6 +150,50 @@ export class VirtualFileSystem { logger.info('VirtualFileSystem stopped'); } + /** + * Reset the VFS to empty state + * Called when meta-sort triggers a fresh scan + * The VFS will be rebuilt incrementally as files are processed via pub/sub + * + * IMPORTANT: This stops the periodic refresh timer to prevent repopulating + * from Redis (which still has old data). The VFS will only update via + * incremental pub/sub events until the next full refresh is triggered. + */ + reset(): void { + logger.info('Resetting VFS for fresh scan...'); + + // Stop periodic refresh to prevent repopulating from stale Redis data + if (this.refreshTimer) { + clearInterval(this.refreshTimer); + this.refreshTimer = null; + logger.info('Periodic refresh timer stopped - VFS will update via pub/sub only'); + } + + this.initRoot(); + this.lastRefresh = null; + logger.info('VFS reset complete - awaiting new file updates from meta-sort'); + } + + /** + * Resume periodic refresh from Redis + * Called after a scan is complete to re-enable auto-refresh + */ + resumePeriodicRefresh(): void { + if (this.refreshTimer) { + logger.debug('Periodic refresh already running'); + return; + } + + logger.info('Resuming periodic refresh from Redis'); + this.refreshTimer = setInterval(async () => { + try { + await this.refresh(); + } catch (error) { + logger.error('Failed to refresh VFS:', error); + } + }, this.config.refreshInterval); + } + /** * Refresh the VFS from Redis * Uses template-based rules if configured, otherwise falls back to MetaDataToFolderStruct