bugfix meta-fuse
This commit is contained in:
@@ -17,6 +17,23 @@ const logger = new Logger({ name: 'meta-fuse' });
|
|||||||
// Pub/sub channel for batched updates from meta-sort
|
// Pub/sub channel for batched updates from meta-sort
|
||||||
const UPDATE_CHANNEL = 'meta-sort:file:batch';
|
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 {
|
interface BatchUpdateMessage {
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
changes: Array<{
|
changes: Array<{
|
||||||
@@ -132,6 +149,39 @@ async function main(): Promise<void> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 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)
|
// Initialize API server (with kvManager for service discovery)
|
||||||
apiServer = new APIServer(vfs, {
|
apiServer = new APIServer(vfs, {
|
||||||
port: config.apiPort,
|
port: config.apiPort,
|
||||||
|
|||||||
@@ -150,6 +150,50 @@ export class VirtualFileSystem {
|
|||||||
logger.info('VirtualFileSystem stopped');
|
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
|
* Refresh the VFS from Redis
|
||||||
* Uses template-based rules if configured, otherwise falls back to MetaDataToFolderStruct
|
* Uses template-based rules if configured, otherwise falls back to MetaDataToFolderStruct
|
||||||
|
|||||||
Reference in New Issue
Block a user