Skip to content

fix: coordinate transaction reminder cron across multiple instances#820

Open
Okorie2000-code wants to merge 1 commit into
MettaChain:mainfrom
Okorie2000-code:fix/696-transaction-reminder-distributed-lock
Open

fix: coordinate transaction reminder cron across multiple instances#820
Okorie2000-code wants to merge 1 commit into
MettaChain:mainfrom
Okorie2000-code:fix/696-transaction-reminder-distributed-lock

Conversation

@Okorie2000-code

Copy link
Copy Markdown

Summary

Prevents duplicate reminder notifications when multiple application instances run the transaction-reminders cron job simultaneously.

Coordination strategy: Redis distributed lock

sendDeadlineReminders now acquires a Redis lock (lock:transaction-reminders) via atomic SET NX EX before processing begins. Any instance that cannot acquire the lock logs a message and returns early — no reminders are sent twice.

  • Lock key: lock:transaction-reminders
  • TTL: 300 s (5 min — exceeds expected job runtime; prevents stale locks on crash)
  • Release: finally block — released on both success and error
  • Infrastructure reused: CacheService.setNx added to the existing CacheService; no new packages

Files changed

File Change
src/cache/cache.service.ts Added setNx(key, value, ttlSeconds) — atomic Redis SET NX EX
src/transactions/transaction-reminders.service.ts Lock acquire/release wrapping processReminders
src/transactions/transaction-reminders.service.spec.ts New: full test coverage for lock scenarios + regression
src/transactions/transactions.module.ts CacheModuleConfig import (already present, no change needed)

Tests

  • ✅ Lock acquired → reminders processed normally
  • ✅ Lock unavailable → processing skipped, no notifications sent
  • ✅ Lock released after success
  • ✅ Lock released after processing error
  • ✅ Regression: buyer/seller notifications, opt-out, dedup, milestone update

Verification

npm test   → 9/9 pass
npm run lint  → 0 errors
npm run build → clean

Closes #696

Introduces a Redis distributed lock in TransactionRemindersService
so only one instance processes reminders per cron window.

- CacheService.setNx: atomic SET NX EX via Redis client
- sendDeadlineReminders acquires lock:transaction-reminders before
  processing; skips if already held
- Lock released in finally block so crashes never leave stale locks
- Lock TTL: 300 s (exceeds expected job runtime)
- Full test coverage: lock acquired, lock unavailable, lock release,
  and regression tests for existing reminder behaviour

Closes MettaChain#696
@drips-wave

drips-wave Bot commented Jun 26, 2026

Copy link
Copy Markdown

@Okorie2000-code Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

transaction-reminders cron runs every minute without distributed lock or jitter

1 participant