129 Zeilen
3.6 KiB
TypeScript
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() |