Files
SkillMate/backend/src/services/syncScheduler.ts
Claude Project Manager 6b9b6d4f20 Initial commit
2025-09-20 21:31:04 +02:00

129 Zeilen
3.6 KiB
TypeScript

import { syncService } from './syncService'
import { db } from '../config/database'
import { logger } from '../utils/logger'
interface SyncInterval {
value: string
milliseconds: number
}
const SYNC_INTERVALS: Record<string, SyncInterval> = {
'5min': { value: '5min', milliseconds: 5 * 60 * 1000 },
'15min': { value: '15min', milliseconds: 15 * 60 * 1000 },
'30min': { value: '30min', milliseconds: 30 * 60 * 1000 },
'1hour': { value: '1hour', milliseconds: 60 * 60 * 1000 },
'daily': { value: 'daily', milliseconds: 24 * 60 * 60 * 1000 }
}
export class SyncScheduler {
private static instance: SyncScheduler
private intervalId: NodeJS.Timeout | null = null
private currentInterval: string = 'disabled'
private constructor() {
this.initialize()
}
static getInstance(): SyncScheduler {
if (!SyncScheduler.instance) {
SyncScheduler.instance = new SyncScheduler()
}
return SyncScheduler.instance
}
private initialize() {
// Check current sync settings on startup
this.checkAndUpdateInterval()
// Check for interval changes every minute
setInterval(() => {
this.checkAndUpdateInterval()
}, 60000)
}
private checkAndUpdateInterval() {
try {
const settings = db.prepare('SELECT auto_sync_interval FROM sync_settings WHERE id = ?').get('default') as any
const newInterval = settings?.auto_sync_interval || 'disabled'
if (newInterval !== this.currentInterval) {
logger.info(`Sync interval changed from ${this.currentInterval} to ${newInterval}`)
this.currentInterval = newInterval
this.updateSchedule()
}
} catch (error) {
logger.error('Failed to check sync interval:', error)
}
}
private updateSchedule() {
// Clear existing interval
if (this.intervalId) {
clearInterval(this.intervalId)
this.intervalId = null
}
// Set new interval if not disabled
if (this.currentInterval !== 'disabled' && SYNC_INTERVALS[this.currentInterval]) {
const { milliseconds } = SYNC_INTERVALS[this.currentInterval]
logger.info(`Starting automatic sync with interval: ${this.currentInterval}`)
// Run sync immediately
this.runSync()
// Then schedule regular syncs
this.intervalId = setInterval(() => {
this.runSync()
}, milliseconds)
} else {
logger.info('Automatic sync disabled')
}
}
private async runSync() {
try {
logger.info('Running scheduled sync...')
// Check if we're the admin node
const nodeType = process.env.NODE_TYPE || 'local'
if (nodeType === 'admin') {
// Admin pushes to all local nodes
await syncService.triggerSync()
} else {
// Local nodes sync with admin
const adminNode = db.prepare(`
SELECT id FROM network_nodes
WHERE type = 'admin' AND is_online = 1
LIMIT 1
`).get() as any
if (adminNode) {
await syncService.syncWithNode(adminNode.id)
} else {
logger.warn('No admin node available for sync')
}
}
logger.info('Scheduled sync completed')
} catch (error) {
logger.error('Scheduled sync failed:', error)
}
}
// Manual trigger for testing
async triggerManualSync() {
await this.runSync()
}
// Get current status
getStatus() {
return {
enabled: this.currentInterval !== 'disabled',
interval: this.currentInterval,
nextRun: this.intervalId ? new Date(Date.now() + (SYNC_INTERVALS[this.currentInterval]?.milliseconds || 0)) : null
}
}
}
export const syncScheduler = SyncScheduler.getInstance()