From 78319a351abe6ca507426e1176131248b8677c52 Mon Sep 17 00:00:00 2001 From: Jeff Mark Date: Sun, 11 Mar 2018 13:40:54 -0700 Subject: [PATCH 1/5] only ping the slack server if clients are actively connected --- lib/index.js | 2 ++ lib/log.js | 7 ++++++- lib/slack.js | 39 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/lib/index.js b/lib/index.js index b4d3b6cc..fd1eaa12 100644 --- a/lib/index.js +++ b/lib/index.js @@ -273,8 +273,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..f169c42e 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 = nil 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') } From becdcdbcec9e94110a6ac4aa76d40c60c87603e1 Mon Sep 17 00:00:00 2001 From: Jeff Mark Date: Sun, 11 Mar 2018 13:45:00 -0700 Subject: [PATCH 2/5] fix --- lib/slack.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/slack.js b/lib/slack.js index f169c42e..ed9a1a6c 100644 --- a/lib/slack.js +++ b/lib/slack.js @@ -12,7 +12,7 @@ export default class SlackData extends EventEmitter { this.org = {} this.users = {} this.clientConnectionCount = 0 - this.fetchTimeout = nil + this.fetchTimeout = null this.channelsByName = {} this.init() this.fetch() From 1023fccce4ac0652a6ebe18250d74e58aa461f6a Mon Sep 17 00:00:00 2001 From: Jeff Mark Date: Mon, 12 Mar 2018 08:39:01 -0700 Subject: [PATCH 3/5] badge.svg requests also restart the fetch interval (client connection) --- lib/index.js | 2 ++ lib/slack.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index fd1eaa12..3b5acaaa 100644 --- a/lib/index.js +++ b/lib/index.js @@ -262,10 +262,12 @@ export default function slackin ({ // badge rendering app.get('/badge.svg', (req, res) => { + slack.clientConnected() res.type('svg') res.set('Cache-Control', 'max-age=0, no-cache') res.set('Pragma', 'no-cache') res.send(badge(slack.users).toHTML()) + setTimeout(slack.clientDisconnected, slack.interval * 4) }) // realtime diff --git a/lib/slack.js b/lib/slack.js index ed9a1a6c..85d60bfd 100644 --- a/lib/slack.js +++ b/lib/slack.js @@ -12,7 +12,7 @@ export default class SlackData extends EventEmitter { this.org = {} this.users = {} this.clientConnectionCount = 0 - this.fetchTimeout = null + this.fetchTimeout = null this.channelsByName = {} this.init() this.fetch() From a874b99b10d293d320052c24d1d1d34917476968 Mon Sep 17 00:00:00 2001 From: Jeff Mark Date: Mon, 12 Mar 2018 09:01:55 -0700 Subject: [PATCH 4/5] fix badge disconnect --- lib/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 3b5acaaa..9561d8bd 100644 --- a/lib/index.js +++ b/lib/index.js @@ -267,7 +267,9 @@ export default function slackin ({ res.set('Cache-Control', 'max-age=0, no-cache') res.set('Pragma', 'no-cache') res.send(badge(slack.users).toHTML()) - setTimeout(slack.clientDisconnected, slack.interval * 4) + setTimeout(function() { + slack.clientDisconnected() + }, slack.interval * 4) }) // realtime From 747214b4fbd08bad7ecaa97bd026e1b0cabcada8 Mon Sep 17 00:00:00 2001 From: Jeff Mark Date: Mon, 12 Mar 2018 09:20:48 -0700 Subject: [PATCH 5/5] allow /data requests to also restart pinging slack --- lib/index.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/index.js b/lib/index.js index 9561d8bd..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,14 +274,11 @@ export default function slackin ({ // badge rendering app.get('/badge.svg', (req, res) => { - slack.clientConnected() + pingSlack() res.type('svg') res.set('Cache-Control', 'max-age=0, no-cache') res.set('Pragma', 'no-cache') res.send(badge(slack.users).toHTML()) - setTimeout(function() { - slack.clientDisconnected() - }, slack.interval * 4) }) // realtime