diff --git a/lib/index.js b/lib/index.js index b4d3b6cc..6901a26f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -79,6 +79,17 @@ export default function slackin ({ app.use(cors()) } + // Temporarily increase the client connection count to allow + // slack to restart the fetch interval (if needed). This allows + // static connections to pull new data if dynamic clients are + // not connected and slack fetching has been paused. + let pingSlack = function() { + slack.clientConnected() + setTimeout(function() { + slack.clientDisconnected() + }, slack.interval * 4) + } + // splash page app.get('/', (req, res) => { let { name, logo } = slack.org @@ -101,6 +112,7 @@ export default function slackin ({ }) app.get('/data', (req, res) => { + pingSlack() let { name, logo } = slack.org let { active, total } = slack.users res.send({ @@ -262,6 +274,7 @@ export default function slackin ({ // badge rendering app.get('/badge.svg', (req, res) => { + pingSlack() res.type('svg') res.set('Cache-Control', 'max-age=0, no-cache') res.set('Pragma', 'no-cache') @@ -273,8 +286,10 @@ export default function slackin ({ socket.emit('data', slack.users) let change = (key, val) => socket.emit(key, val) slack.on('change', change) + slack.clientConnected() socket.on('disconnect', () => { slack.removeListener('change', change) + slack.clientDisconnected() }) }) diff --git a/lib/log.js b/lib/log.js index 9e2fde1b..ad2a4b82 100644 --- a/lib/log.js +++ b/lib/log.js @@ -16,13 +16,18 @@ export default function log (slack, silent){ out('fetching') }) + slack.on('log', (message) => { + out(message) + }) + slack.on('data', online) // log online users function online (){ - out('online %d, total %d %s', + out('online %d, total %d, clients %d %s', slack.users.active, slack.users.total, + slack.clientConnectionCount, last ? `(+${new Date - last}ms)` : '') } diff --git a/lib/slack.js b/lib/slack.js index 5de4306e..85d60bfd 100644 --- a/lib/slack.js +++ b/lib/slack.js @@ -11,6 +11,8 @@ export default class SlackData extends EventEmitter { this.ready = false this.org = {} this.users = {} + this.clientConnectionCount = 0 + this.fetchTimeout = null this.channelsByName = {} this.init() this.fetch() @@ -44,7 +46,36 @@ export default class SlackData extends EventEmitter { }) } + clientConnected() { + if (this.clientConnectionCount == 0) { + this.emit('log', 'restarting fetch') + this.fetch() + } + this.clientConnectionCount++ + } + + clientDisconnected() { + this.clientConnectionCount-- + if (this.clientConnectionCount == 0) { + this.emit('log', 'pausing fetch') + this.stopFetchTimeout() + } + } + + stopFetchTimeout() { + if (this.fetchTimeout) { + clearTimeout(this.fetchTimeout) + this.fetchTimeout = null + } + } + + retryFetch(interval) { + this.stopFetchTimeout() + this.fetchTimeout = setTimeout(this.fetch.bind(this), interval) + } + fetch (){ + this.stopFetchTimeout() request .get(`https://${this.host}.slack.com/api/users.list`) .query({ token: this.token, presence: 1 }) @@ -59,9 +90,9 @@ export default class SlackData extends EventEmitter { return channel ? channel.id: null } - retry (){ + retry () { let interval = this.interval * 2 - setTimeout(this.fetch.bind(this), interval) + this.retryFetch(interval) this.emit('retry') } @@ -107,7 +138,9 @@ export default class SlackData extends EventEmitter { this.emit('ready') } - setTimeout(this.fetch.bind(this), this.interval) + if (this.clientConnectionCount > 0) { + this.retryFetch(this.interval) + } this.emit('data') }