Skip to content

Instantly share code, notes, and snippets.

@danneu
Last active June 25, 2017 02:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danneu/80a4ec4bcec58b4c49360483d0adc8d8 to your computer and use it in GitHub Desktop.
Save danneu/80a4ec4bcec58b4c49360483d0adc8d8 to your computer and use it in GitHub Desktop.
'use strict'
// 3rd
const uuid = require('uuid')
const debug = require('debug')('app:middleware:track')
// 1st
const db = require('../db')
const {isValidUuid, futureDate} = require('../belt')
module.exports = ({cookieKey = 't', interval = 5000} = {}) => {
debug('initializing track middleware')
let queue = []
const clearQueue = () => {
debug('[clearQueue] queue = %j', queue)
if (queue.length === 0) {
return setTimeout(clearQueue, interval)
}
const hits = queue.slice(0)
queue = []
db.hits.insertHits(hits)
.then(() => {
debug(`${hits.length} hits inserted`)
setTimeout(clearQueue, interval)
}, (err) => {
console.error('[track middleware] error inserting hits', err)
setTimeout(clearQueue, interval)
})
}
// Start loop
setTimeout(clearQueue, interval)
return async (ctx, next) => {
// Skip guests
if (!ctx.currUser) {
return next()
}
let track
if (isValidUuid(ctx.cookies.get(cookieKey))) {
track = ctx.cookies.get(cookieKey)
} else {
track = uuid.v4()
ctx.cookies.set(cookieKey, track, {
expires: futureDate({ years: 1 })
})
}
// Expose track downstream
ctx.state.track = track
await next()
// Wait til after downstream so that we don't
// push a hit on errors.
queue.push({
user_id: ctx.currUser.id,
ip_address: ctx.ip,
track
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment