import { Observable } from 'rx'; import debug from 'debug'; import { reportError } from '../middlewares/error-reporter'; import InMemoryCache from '../utils/in-memory-cache'; const log = debug('fcc:boot:donate'); const fiveMinutes = 1000 * 60 * 5; export default function(Donation) { let activeDonationUpdateInterval = null; const activeDonationCountCacheTTL = fiveMinutes; const activeDonationCountCache = InMemoryCache(0, reportError); const activeDonationsQuery$ = () => Donation.find$({ // eslint-disable-next-line no-undefined where: { endDate: undefined } }).map(instances => instances.length); function cleanUp() { if (activeDonationUpdateInterval) { clearInterval(activeDonationUpdateInterval); } return; } process.on('exit', cleanUp); Donation.on('dataSourceAttached', () => { Donation.find$ = Observable.fromNodeCallback(Donation.find.bind(Donation)); Donation.findOne$ = Observable.fromNodeCallback( Donation.findOne.bind(Donation) ); seedTheCache() .then(setupCacheUpdateInterval) .catch(err => { const errMsg = `Error caught seeding the cache: ${err.message}`; err.message = errMsg; reportError(err); }); }); function seedTheCache() { return new Promise((resolve, reject) => Observable.defer(activeDonationsQuery$).subscribe(count => { log('activeDonator count: %d', count); activeDonationCountCache.update(() => count); return resolve(); }, reject) ); } function setupCacheUpdateInterval() { activeDonationUpdateInterval = setInterval( () => Observable.defer(activeDonationsQuery$).subscribe( count => { log('activeDonator count: %d', count); return activeDonationCountCache.update(() => count); }, err => { const errMsg = `Error caught updating the cache: ${err.message}`; err.message = errMsg; reportError(err); } ), activeDonationCountCacheTTL ); return null; } function getCurrentActiveDonationCount$() { return Observable.of(activeDonationCountCache.get()); } Donation.getCurrentActiveDonationCount$ = getCurrentActiveDonationCount$; }