From 526251397e3bcb6e9872b0d547f1d06955f3e887 Mon Sep 17 00:00:00 2001 From: Harry Adel Date: Tue, 20 Jan 2026 17:56:52 +0200 Subject: [PATCH] Migrate from percolate:synced-cron to quave:synced-cron --- .meteor/packages | 2 +- .meteor/versions | 2 +- models/users.js | 2 +- packages/wekan-ldap/package.js | 2 +- packages/wekan-ldap/server/sync.js | 4 ++-- server/00checkStartup.js | 2 +- server/cronMigrationManager.js | 37 ++++++++++++++++++++++-------- 7 files changed, 35 insertions(+), 16 deletions(-) diff --git a/.meteor/packages b/.meteor/packages index b88d7b8c2..92234d4e6 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -69,7 +69,7 @@ meteorhacks:subs-manager meteorhacks:aggregate@1.3.0 wekan-markdown konecty:mongo-counter -percolate:synced-cron +quave:synced-cron ostrio:cookies ostrio:files@2.3.0 lmieulet:meteor-coverage diff --git a/.meteor/versions b/.meteor/versions index b2a89f8ea..3487f7653 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -105,8 +105,8 @@ peerlibrary:blaze-components@0.23.0 peerlibrary:computed-field@0.10.0 peerlibrary:data-lookup@0.3.0 peerlibrary:reactive-field@0.6.0 -percolate:synced-cron@1.5.2 promise@0.12.2 +quave:synced-cron@2.2.1 raix:eventemitter@0.1.3 raix:handlebar-helpers@0.2.5 random@1.2.1 diff --git a/models/users.js b/models/users.js index 501dfae0a..f61bdb1c0 100644 --- a/models/users.js +++ b/models/users.js @@ -1,6 +1,6 @@ import { ReactiveCache, ReactiveMiniMongoIndex } from '/imports/reactiveCache'; import { Random } from 'meteor/random'; -import { SyncedCron } from 'meteor/percolate:synced-cron'; +import { SyncedCron } from 'meteor/quave:synced-cron'; import { TAPi18n } from '/imports/i18n'; import ImpersonatedUsers from './impersonatedUsers'; // import { Index, MongoDBEngine } from 'meteor/easy:search'; // Temporarily disabled due to compatibility issues diff --git a/packages/wekan-ldap/package.js b/packages/wekan-ldap/package.js index 57a2ede35..e3da7243b 100644 --- a/packages/wekan-ldap/package.js +++ b/packages/wekan-ldap/package.js @@ -20,7 +20,7 @@ Package.onUse(function(api) { api.use('accounts-base', 'server'); api.use('accounts-password', 'server'); - api.use('percolate:synced-cron', 'server'); + api.use('quave:synced-cron', 'server'); api.addFiles('client/loginHelper.js', 'client'); api.mainModule('server/index.js', 'server'); diff --git a/packages/wekan-ldap/server/sync.js b/packages/wekan-ldap/server/sync.js index efe7e35f3..0da3e2246 100644 --- a/packages/wekan-ldap/server/sync.js +++ b/packages/wekan-ldap/server/sync.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import SyncedCron from 'meteor/percolate:synced-cron'; +import { SyncedCron } from 'meteor/quave:synced-cron'; import LDAP from './ldap'; import { log_debug, log_info, log_warn, log_error } from './logger'; @@ -440,7 +440,7 @@ function sync() { const jobName = 'LDAP_Sync'; const addCronJob = _.debounce(Meteor.bindEnvironment(function addCronJobDebounced() { - let sc=SyncedCron.SyncedCron; //Why ?? something must be wrong in the import + let sc = SyncedCron; if (LDAP.settings_get('LDAP_BACKGROUND_SYNC') !== true) { log_info('Disabling LDAP Background Sync'); if (sc.nextScheduledAtDate(jobName)) { diff --git a/server/00checkStartup.js b/server/00checkStartup.js index ed4dbabb3..8cf8f69e5 100644 --- a/server/00checkStartup.js +++ b/server/00checkStartup.js @@ -4,7 +4,7 @@ const os = require('os'); // Configure SyncedCron to suppress console logging // This must be done before any SyncedCron operations if (Meteor.isServer) { - const { SyncedCron } = require('meteor/percolate:synced-cron'); + const { SyncedCron } = require('meteor/quave:synced-cron'); SyncedCron.config({ log: false, // Disable console logging collectionName: 'cronJobs', // Use custom collection name diff --git a/server/cronMigrationManager.js b/server/cronMigrationManager.js index 9b0b7faab..2b9d1777b 100644 --- a/server/cronMigrationManager.js +++ b/server/cronMigrationManager.js @@ -4,7 +4,7 @@ */ import { Meteor } from 'meteor/meteor'; -import { SyncedCron } from 'meteor/percolate:synced-cron'; +import { SyncedCron } from 'meteor/quave:synced-cron'; import { ReactiveVar } from 'meteor/reactive-var'; import { cronJobStorage } from './cronJobStorage'; @@ -28,6 +28,7 @@ class CronMigrationManager { this.isRunning = false; this.jobProcessor = null; this.processingInterval = null; + this.pausedJobs = new Map(); // Store paused job configs for per-job pause/resume } /** @@ -797,7 +798,7 @@ class CronMigrationManager { */ async startCronJob(cronName) { // Change schedule to run once - const job = SyncedCron.jobs.find(j => j.name === cronName); + const job = SyncedCron._entries?.[cronName]; if (job) { job.schedule = 'once'; SyncedCron.start(); @@ -832,9 +833,20 @@ class CronMigrationManager { /** * Pause a specific cron job + * Note: quave:synced-cron only has global pause(), so we implement per-job pause + * by storing the job config and removing it, then re-adding on resume. */ pauseCronJob(cronName) { - SyncedCron.pause(cronName); + const entry = SyncedCron._entries?.[cronName]; + if (entry) { + // Store the job config before removing + this.pausedJobs.set(cronName, { + name: entry.name, + schedule: entry.schedule, + job: entry.job + }); + SyncedCron.remove(cronName); + } const step = this.migrationSteps.find(s => s.cronName === cronName); if (step) { step.status = 'paused'; @@ -844,9 +856,15 @@ class CronMigrationManager { /** * Resume a specific cron job + * Note: quave:synced-cron doesn't have resume(), so we re-add the stored job config. */ resumeCronJob(cronName) { - SyncedCron.resume(cronName); + const pausedJob = this.pausedJobs.get(cronName); + if (pausedJob) { + SyncedCron.add(pausedJob); + this.pausedJobs.delete(cronName); + SyncedCron.start(); + } const step = this.migrationSteps.find(s => s.cronName === cronName); if (step) { step.status = 'running'; @@ -902,14 +920,15 @@ class CronMigrationManager { * Update cron jobs list */ updateCronJobsList() { - // Check if SyncedCron is available and has jobs - if (!SyncedCron || !SyncedCron.jobs || !Array.isArray(SyncedCron.jobs)) { + // Check if SyncedCron is available and has entries + const entries = SyncedCron?._entries; + if (!entries || typeof entries !== 'object') { // SyncedCron not available or no jobs yet cronJobs.set([]); return; } - const jobs = SyncedCron.jobs.map(job => { + const jobs = Object.values(entries).map(job => { const step = this.migrationSteps.find(s => s.cronName === job.name); return { name: job.name, @@ -1332,8 +1351,8 @@ class CronMigrationManager { clearAllCronJobs() { try { // Stop all existing cron jobs - if (SyncedCron && SyncedCron.jobs) { - SyncedCron.jobs.forEach(job => { + if (SyncedCron?._entries) { + Object.values(SyncedCron._entries).forEach(job => { try { SyncedCron.remove(job.name); } catch (error) {