Add timed cache to user count queries
This commit is contained in:
@ -2,40 +2,43 @@ import { Observable } from 'rx';
|
||||
import dedent from 'dedent';
|
||||
import moment from 'moment';
|
||||
|
||||
import { observeMethod } from '../utils/rx';
|
||||
import { timeCache, observeMethod } from '../utils/rx';
|
||||
|
||||
function numberWithCommas(x) {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
}
|
||||
|
||||
// userCount(where: Object) => Observable[Number]
|
||||
// getCertCount(userCount: userCount, cert: String) => Observable[Number]
|
||||
function getCertCount(userCount, cert) {
|
||||
return userCount({ [cert]: true })
|
||||
// using This-Bind operator
|
||||
::timeCache(2, 'hours');
|
||||
}
|
||||
|
||||
export default function about(app) {
|
||||
const router = app.loopback.Router();
|
||||
const User = app.models.User;
|
||||
const userCount$ = observeMethod(User, 'count');
|
||||
const userCount = observeMethod(User, 'count');
|
||||
const frontEndCount$ = getCertCount(userCount, 'isFrontEndCert');
|
||||
const dataVisCount$ = getCertCount(userCount, 'isDataVisCert');
|
||||
const backEndCount$ = getCertCount(userCount, 'isBackEndCert');
|
||||
|
||||
function showAbout(req, res, next) {
|
||||
const daysRunning = moment().diff(new Date('10/15/2014'), 'days');
|
||||
|
||||
Observable.combineLatest(
|
||||
userCount$(),
|
||||
userCount$({ isFrontEndCert: true }),
|
||||
userCount$({ isDataVisCert: true }),
|
||||
userCount$({ isBackEndCert: true }),
|
||||
(
|
||||
userCount,
|
||||
frontEndCount = 0,
|
||||
dataVisCount = 0,
|
||||
backEndCount = 0
|
||||
) => ({
|
||||
userCount: numberWithCommas(userCount),
|
||||
frontEndCount$,
|
||||
dataVisCount$,
|
||||
backEndCount$,
|
||||
(frontEndCount = 0, dataVisCount = 0, backEndCount = 0) => ({
|
||||
frontEndCount,
|
||||
dataVisCount,
|
||||
backEndCount
|
||||
})
|
||||
)
|
||||
.doOnNext(({ userCount, frontEndCount, dataVisCount, backEndCount }) => {
|
||||
.doOnNext(({ frontEndCount, dataVisCount, backEndCount }) => {
|
||||
res.render('resources/about', {
|
||||
userCount,
|
||||
frontEndCount,
|
||||
dataVisCount,
|
||||
backEndCount,
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Rx from 'rx';
|
||||
import Rx, { AsyncSubject, Observable } from 'rx';
|
||||
import moment from 'moment';
|
||||
import debugFactory from 'debug';
|
||||
|
||||
const debug = debugFactory('fcc:rxUtils');
|
||||
@ -31,3 +32,22 @@ export function observeQuery(Model, method, query) {
|
||||
export function observeMethod(context, methodName) {
|
||||
return Rx.Observable.fromNodeCallback(context[methodName], context);
|
||||
}
|
||||
|
||||
// timeChache(amount: Number, unit: String) => Observable
|
||||
export function timeCache(time, unit) {
|
||||
const source = this;
|
||||
let cache;
|
||||
let expireCacheAt;
|
||||
return Observable.create(observable => {
|
||||
// if there is no expire time set
|
||||
// or if expireCacheAt is smaller than now,
|
||||
// set new expire time in MS and create new subscription to source
|
||||
if (!expireCacheAt || expireCacheAt < Date.now()) {
|
||||
// set expire in ms;
|
||||
expireCacheAt = moment().add(time, unit).valueOf();
|
||||
cache = new AsyncSubject();
|
||||
source.subscribe(cache);
|
||||
}
|
||||
return cache.subscribe(observable);
|
||||
});
|
||||
}
|
||||
|
@ -9,14 +9,6 @@ block content
|
||||
span.tag Established:	
|
||||
span.text-primary #{daysRunning}
|
||||
| days ago
|
||||
li
|
||||
span.tag Population:	
|
||||
span.text-primary #{userCount}
|
||||
| campers
|
||||
li
|
||||
span.tag Completed:	
|
||||
span.text-primary #{globalCompletedCount}
|
||||
| challenges
|
||||
li.nowrap
|
||||
span.tag Donated:	
|
||||
span.text-primary $850,000
|
||||
|
Reference in New Issue
Block a user