nodebb-plugin-onekite-calendar 2.0.28 → 2.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog – calendar-onekite
2
2
 
3
+ ## 1.3.26
4
+ - Scheduler : garde "send-once" rendue **atomique** en multi-instance (priorité à `db.incrObjectField(key, rid)`), pour garantir qu'au moins une instance envoie les emails/Discord avant suppression.
5
+ - Scheduler : en cas d'erreur DB sur la garde, on **privilégie l'envoi** plutôt que "expire sans email" (dernier recours : autoriser l'envoi même si la garde échoue).
6
+
7
+ ## 1.3.25
8
+ - Scheduler : correction robuste du mécanisme "send-once" en environnement multi-process (utilise `db.incrObjectField` quand disponible).
9
+ - Fix : évite le cas "réservation expirée/supprimée sans email/Discord" lorsque la DB ne supporte pas correctement les sets/objets utilisés comme garde.
10
+
11
+ ## 1.3.24
12
+ - Multi-process : le scheduler ne démarre pas si NodeBB a `runJobs=false` (évite les exécutions multiples de jobs en cluster).
13
+
3
14
  ## 1.3.23
4
15
  - Scheduler (paiement en attente) : correction de la garde "send-once" pour compatibilité avec tous les adaptateurs DB NodeBB (fallback si `db.setAdd` n'est pas disponible).
5
16
  - Scheduler : les erreurs ne sont plus avalées silencieusement (logs `Scheduler error ...`).
package/lib/scheduler.js CHANGED
@@ -16,6 +16,18 @@ async function addOnce(key, value) {
16
16
  const v = String(value);
17
17
  if (!v) return false;
18
18
 
19
+ // Best-effort atomic guard across multi-process / multi-instance.
20
+ // incrObjectField is implemented by most NodeBB DB adapters (Redis/Mongo).
21
+ // If it exists, it gives us a reliable "first winner" (value === 1).
22
+ if (typeof db.incrObjectField === 'function') {
23
+ try {
24
+ const n = await db.incrObjectField(key, v);
25
+ return Number(n) === 1;
26
+ } catch (e) {
27
+ // fall through
28
+ }
29
+ }
30
+
19
31
  // Preferred atomic helper (Redis + some adapters)
20
32
  if (typeof db.setAdd === 'function') {
21
33
  try {
@@ -33,7 +45,9 @@ async function addOnce(key, value) {
33
45
  await db.setObjectField(key, v, 1);
34
46
  return true;
35
47
  } catch (e) {
36
- return false;
48
+ // Last resort: allow sending rather than silently doing nothing.
49
+ // This may duplicate emails in edge cases, but avoids "expires with no email".
50
+ return true;
37
51
  }
38
52
  }
39
53
 
@@ -419,7 +433,15 @@ async function processAwaitingPayment() {
419
433
  }
420
434
 
421
435
  function start() {
436
+ const runJobs = nconf.get('runJobs');
437
+ if (runJobs === false || runJobs === 'false' || runJobs === 0 || runJobs === '0') {
438
+ // eslint-disable-next-line no-console
439
+ console.info('[calendar-onekite] Scheduler disabled (runJobs=false)');
440
+ return;
441
+ }
422
442
  if (timer) return;
443
+ // eslint-disable-next-line no-console
444
+ console.info('[calendar-onekite] Scheduler enabled');
423
445
  timer = setInterval(() => {
424
446
  expirePending().catch((err) => {
425
447
  // eslint-disable-next-line no-console
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-onekite-calendar",
3
- "version": "2.0.28",
3
+ "version": "2.0.30",
4
4
  "description": "FullCalendar-based equipment reservation workflow with admin approval & HelloAsso payment for NodeBB",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/plugin.json CHANGED
@@ -39,5 +39,5 @@
39
39
  "acpScripts": [
40
40
  "public/admin.js"
41
41
  ],
42
- "version": "2.0.28"
42
+ "version": "2.0.30"
43
43
  }