bugfix
This commit is contained in:
@@ -38,7 +38,6 @@ export class UnifiedAPIServer {
|
|||||||
private getDuplicateResult: (() => DuplicateResult | null) | null = null;
|
private getDuplicateResult: (() => DuplicateResult | null) | null = null;
|
||||||
private kvClient: IKVClient | null = null;
|
private kvClient: IKVClient | null = null;
|
||||||
private kvManager: KVManager | null = null;
|
private kvManager: KVManager | null = null;
|
||||||
private triggerScanCallback: (() => Promise<void>) | null = null;
|
|
||||||
private getQueueStatus: (() => any) | null = null;
|
private getQueueStatus: (() => any) | null = null;
|
||||||
private fastQueueConcurrency: number | undefined = undefined;
|
private fastQueueConcurrency: number | undefined = undefined;
|
||||||
private backgroundQueueConcurrency: number | undefined = undefined;
|
private backgroundQueueConcurrency: number | undefined = undefined;
|
||||||
@@ -59,7 +58,6 @@ export class UnifiedAPIServer {
|
|||||||
unifiedStateManager?: UnifiedProcessingStateManager,
|
unifiedStateManager?: UnifiedProcessingStateManager,
|
||||||
getDuplicateResult?: () => DuplicateResult | null,
|
getDuplicateResult?: () => DuplicateResult | null,
|
||||||
kvClient?: IKVClient,
|
kvClient?: IKVClient,
|
||||||
triggerScanCallback?: () => Promise<void>,
|
|
||||||
backgroundQueueConcurrency?: number,
|
backgroundQueueConcurrency?: number,
|
||||||
fastQueueConcurrency?: number,
|
fastQueueConcurrency?: number,
|
||||||
getQueueStatus?: () => any,
|
getQueueStatus?: () => any,
|
||||||
@@ -72,7 +70,6 @@ export class UnifiedAPIServer {
|
|||||||
this.getDuplicateResult = getDuplicateResult || null;
|
this.getDuplicateResult = getDuplicateResult || null;
|
||||||
this.kvClient = kvClient || null;
|
this.kvClient = kvClient || null;
|
||||||
this.kvManager = kvManager || null;
|
this.kvManager = kvManager || null;
|
||||||
this.triggerScanCallback = triggerScanCallback || null;
|
|
||||||
this.getQueueStatus = getQueueStatus || null;
|
this.getQueueStatus = getQueueStatus || null;
|
||||||
this.backgroundQueueConcurrency = backgroundQueueConcurrency;
|
this.backgroundQueueConcurrency = backgroundQueueConcurrency;
|
||||||
this.fastQueueConcurrency = fastQueueConcurrency;
|
this.fastQueueConcurrency = fastQueueConcurrency;
|
||||||
@@ -724,12 +721,6 @@ export class UnifiedAPIServer {
|
|||||||
// Add file back to discovered state for reprocessing
|
// Add file back to discovered state for reprocessing
|
||||||
this.unifiedStateManager!.addDiscovered(filePath);
|
this.unifiedStateManager!.addDiscovered(filePath);
|
||||||
|
|
||||||
// Trigger scan callback if available to pick up the file
|
|
||||||
if (this.triggerScanCallback) {
|
|
||||||
// Don't await - just trigger async
|
|
||||||
this.triggerScanCallback().catch(err => console.warn('[API] Scan trigger failed during retry:', getErrorMessage(err)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return { status: 'ok', message: `File ${filePath} queued for retry` };
|
return { status: 'ok', message: `File ${filePath} queued for retry` };
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return reply.status(500).send({ error: error.message });
|
return reply.status(500).send({ error: error.message });
|
||||||
@@ -747,11 +738,6 @@ export class UnifiedAPIServer {
|
|||||||
queued++;
|
queued++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger scan callback if available
|
|
||||||
if (this.triggerScanCallback) {
|
|
||||||
this.triggerScanCallback().catch(err => console.warn('[API] Scan trigger failed during retry-all:', getErrorMessage(err)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return { status: 'ok', message: `${queued} files queued for retry` };
|
return { status: 'ok', message: `${queued} files queued for retry` };
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -883,40 +869,12 @@ export class UnifiedAPIServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup Scan Trigger API routes
|
* Setup Metadata Clear API routes
|
||||||
|
* NOTE: /api/scan/trigger has been removed - use meta-core's endpoint instead
|
||||||
*/
|
*/
|
||||||
private setupScanRoutes(): void {
|
private setupScanRoutes(): void {
|
||||||
// Trigger manual scan
|
// Clear all metadata
|
||||||
this.app.post('/api/scan/trigger', async (request, reply) => {
|
// NOTE: To trigger a rescan after clearing, call meta-core's /api/scan/trigger endpoint
|
||||||
if (!this.triggerScanCallback) {
|
|
||||||
return reply.status(503).send({
|
|
||||||
status: 'error',
|
|
||||||
message: 'Scan trigger not available'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log('Manual scan triggered via API');
|
|
||||||
// Don't await - trigger and return immediately
|
|
||||||
this.triggerScanCallback().catch(error => {
|
|
||||||
console.error('Error during triggered scan:', error);
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
status: 'ok',
|
|
||||||
message: 'Scan triggered successfully'
|
|
||||||
};
|
|
||||||
} catch (error: any) {
|
|
||||||
console.error('Error triggering scan:', error);
|
|
||||||
return reply.status(500).send({
|
|
||||||
status: 'error',
|
|
||||||
message: 'Failed to trigger scan',
|
|
||||||
details: error.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Clear all metadata and trigger rescan
|
|
||||||
this.app.post('/api/metadata/clear', async (request, reply) => {
|
this.app.post('/api/metadata/clear', async (request, reply) => {
|
||||||
if (!this.kvClient) {
|
if (!this.kvClient) {
|
||||||
return reply.status(503).send({
|
return reply.status(503).send({
|
||||||
@@ -950,19 +908,10 @@ export class UnifiedAPIServer {
|
|||||||
|
|
||||||
console.log(`Cleared ${deletedCount} file metadata entries`);
|
console.log(`Cleared ${deletedCount} file metadata entries`);
|
||||||
|
|
||||||
// Trigger rescan if callback is available
|
|
||||||
if (this.triggerScanCallback) {
|
|
||||||
console.log('Triggering rescan after metadata clear');
|
|
||||||
this.triggerScanCallback().catch(error => {
|
|
||||||
console.error('Error during post-clear rescan:', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 'ok',
|
status: 'ok',
|
||||||
message: `Cleared ${deletedCount} files`,
|
message: `Cleared ${deletedCount} files. To rescan, call meta-core's /api/scan/trigger endpoint.`,
|
||||||
deletedCount,
|
deletedCount
|
||||||
rescanTriggered: !!this.triggerScanCallback
|
|
||||||
};
|
};
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('Error clearing metadata:', error);
|
console.error('Error clearing metadata:', error);
|
||||||
@@ -1964,7 +1913,6 @@ export class UnifiedAPIServer {
|
|||||||
if (this.unifiedStateManager) {
|
if (this.unifiedStateManager) {
|
||||||
console.log(` - Unified Processing API (4 states): http://${this.config.host}:${this.config.port}/api/processing/status`);
|
console.log(` - Unified Processing API (4 states): http://${this.config.host}:${this.config.port}/api/processing/status`);
|
||||||
}
|
}
|
||||||
console.log(` - Scan API: http://${this.config.host}:${this.config.port}/api/scan/trigger (POST)`);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error starting Unified API Server:', error);
|
console.error('Error starting Unified API Server:', error);
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -270,7 +270,6 @@ describe('UnifiedAPIServer', function() {
|
|||||||
mockStateManager as any,
|
mockStateManager as any,
|
||||||
() => duplicateResult,
|
() => duplicateResult,
|
||||||
mockKV as any,
|
mockKV as any,
|
||||||
async () => { /* scan trigger */ },
|
|
||||||
4, // backgroundQueueConcurrency
|
4, // backgroundQueueConcurrency
|
||||||
16, // fastQueueConcurrency
|
16, // fastQueueConcurrency
|
||||||
() => ({ fast: { pending: 0, running: 0 }, background: { pending: 0, running: 0 } })
|
() => ({ fast: { pending: 0, running: 0 }, background: { pending: 0, running: 0 } })
|
||||||
@@ -463,20 +462,8 @@ describe('UnifiedAPIServer', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// =========================================================================
|
// NOTE: /api/scan/trigger has been removed from meta-sort (Architecture V3)
|
||||||
// Scan API
|
// Scan is now handled by meta-core. Tests for scan trigger are in core.bats.
|
||||||
// =========================================================================
|
|
||||||
|
|
||||||
describe('Scan API (/api/scan)', function() {
|
|
||||||
it('POST /api/scan/trigger triggers a scan', async function() {
|
|
||||||
const response = await app.inject({
|
|
||||||
method: 'POST',
|
|
||||||
url: '/api/scan/trigger'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect([200, 202, 204]).to.include(response.statusCode);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// FUSE API (Virtual Filesystem)
|
// FUSE API (Virtual Filesystem)
|
||||||
|
|||||||
@@ -98,24 +98,8 @@ export class EventSubscriber {
|
|||||||
console.log('[EventSubscriber] Stopped');
|
console.log('[EventSubscriber] Stopped');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// NOTE: triggerScan() has been removed - meta-core handles scanning automatically
|
||||||
* Trigger a manual scan on meta-core
|
// To trigger a scan manually, call meta-core's /api/scan/trigger endpoint directly
|
||||||
*/
|
|
||||||
async triggerScan(): Promise<void> {
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${this.options.metaCoreUrl}/api/scan/trigger`, {
|
|
||||||
method: 'POST'
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`HTTP ${response.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('[EventSubscriber] Scan triggered on meta-core');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[EventSubscriber] Failed to trigger scan:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get watcher status from meta-core
|
* Get watcher status from meta-core
|
||||||
@@ -171,13 +155,7 @@ export class EventSubscriber {
|
|||||||
this.eventSource.onopen = () => {
|
this.eventSource.onopen = () => {
|
||||||
console.log('[EventSubscriber] Connected to meta-core SSE');
|
console.log('[EventSubscriber] Connected to meta-core SSE');
|
||||||
this.reconnectAttempts = 0;
|
this.reconnectAttempts = 0;
|
||||||
|
// NOTE: Initial scan is handled automatically by meta-core (Architecture V3)
|
||||||
// Request initial scan if configured
|
|
||||||
if (this.options.requestInitialScan) {
|
|
||||||
this.triggerScan().catch(err => {
|
|
||||||
console.error('[EventSubscriber] Failed to trigger initial scan:', err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.eventSource.onerror = (error) => {
|
this.eventSource.onerror = (error) => {
|
||||||
|
|||||||
@@ -79,22 +79,8 @@ const getDuplicateResult = () => fileProcessor.getDuplicateResult();
|
|||||||
// API Server will be initialized after KV is ready (deferred to async init)
|
// API Server will be initialized after KV is ready (deferred to async init)
|
||||||
let apiServer: UnifiedAPIServer | null = null;
|
let apiServer: UnifiedAPIServer | null = null;
|
||||||
|
|
||||||
// Manual scan trigger (called from API) - delegates to meta-core via EventSubscriber
|
// NOTE: Scan trigger has been moved to meta-core (Architecture V3)
|
||||||
const triggerScan = async () => {
|
// Use meta-core's /api/scan/trigger endpoint directly
|
||||||
console.log('[Scan] Triggering manual scan...');
|
|
||||||
|
|
||||||
// Reset pipeline counters and state before fresh scan
|
|
||||||
// Also publishes reset event to meta-fuse
|
|
||||||
await pipeline.reset();
|
|
||||||
|
|
||||||
// Trigger scan on meta-core (which will send events back via SSE)
|
|
||||||
if (eventSubscriber) {
|
|
||||||
await eventSubscriber.triggerScan();
|
|
||||||
console.log('[Scan] Scan triggered on meta-core');
|
|
||||||
} else {
|
|
||||||
console.warn('[Scan] EventSubscriber not available, cannot trigger scan');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Global error handlers - prevent crashes from unforeseen errors
|
// Global error handlers - prevent crashes from unforeseen errors
|
||||||
process.on('uncaughtException', (error: Error) => {
|
process.on('uncaughtException', (error: Error) => {
|
||||||
@@ -178,7 +164,7 @@ process.on('SIGINT', async () => {
|
|||||||
port: config.FUSE_API_PORT,
|
port: config.FUSE_API_PORT,
|
||||||
host: config.FUSE_API_HOST,
|
host: config.FUSE_API_HOST,
|
||||||
enableCors: true,
|
enableCors: true,
|
||||||
}, unifiedStateManager, getDuplicateResult, kvClient || undefined, triggerScan, backgroundQueueConcurrency, fastQueueConcurrency, () => fileProcessor.getQueueStatus(), kvManager || undefined, getPluginManagerInstance, () => fileProcessor.getTaskScheduler());
|
}, unifiedStateManager, getDuplicateResult, kvClient || undefined, backgroundQueueConcurrency, fastQueueConcurrency, () => fileProcessor.getQueueStatus(), kvManager || undefined, getPluginManagerInstance, () => fileProcessor.getTaskScheduler());
|
||||||
|
|
||||||
await apiServer.start();
|
await apiServer.start();
|
||||||
console.log('Unified API Server started successfully');
|
console.log('Unified API Server started successfully');
|
||||||
@@ -269,7 +255,7 @@ process.on('SIGINT', async () => {
|
|||||||
console.error('[Startup] Make sure meta-core is running and kv-leader.info exists.');
|
console.error('[Startup] Make sure meta-core is running and kv-leader.info exists.');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
const metaCoreUrl = leaderInfo.baseUrl;
|
const metaCoreUrl = leaderInfo.apiUrl;
|
||||||
console.log(`[Startup] Connecting to meta-core at ${metaCoreUrl}...`);
|
console.log(`[Startup] Connecting to meta-core at ${metaCoreUrl}...`);
|
||||||
eventSubscriber = new EventSubscriber({
|
eventSubscriber = new EventSubscriber({
|
||||||
metaCoreUrl: metaCoreUrl,
|
metaCoreUrl: metaCoreUrl,
|
||||||
|
|||||||
Reference in New Issue
Block a user