DrainManager.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. const logger = require('logger-sharelatex')
  2. module.exports = {
  3. startDrainTimeWindow(io, minsToDrain) {
  4. const drainPerMin = io.sockets.clients().length / minsToDrain
  5. // enforce minimum drain rate
  6. this.startDrain(io, Math.max(drainPerMin / 60, 4))
  7. },
  8. startDrain(io, rate) {
  9. // Clear out any old interval
  10. clearInterval(this.interval)
  11. logger.log({ rate }, 'starting drain')
  12. if (rate === 0) {
  13. return
  14. }
  15. let pollingInterval
  16. if (rate < 1) {
  17. // allow lower drain rates
  18. // e.g. rate=0.1 will drain one client every 10 seconds
  19. pollingInterval = 1000 / rate
  20. rate = 1
  21. } else {
  22. pollingInterval = 1000
  23. }
  24. this.interval = setInterval(() => {
  25. this.reconnectNClients(io, rate)
  26. }, pollingInterval)
  27. },
  28. RECONNECTED_CLIENTS: {},
  29. reconnectNClients(io, N) {
  30. let drainedCount = 0
  31. for (const client of io.sockets.clients()) {
  32. if (!this.RECONNECTED_CLIENTS[client.id]) {
  33. this.RECONNECTED_CLIENTS[client.id] = true
  34. logger.log(
  35. { client_id: client.id },
  36. 'Asking client to reconnect gracefully'
  37. )
  38. client.emit('reconnectGracefully')
  39. drainedCount++
  40. }
  41. const haveDrainedNClients = drainedCount === N
  42. if (haveDrainedNClients) {
  43. break
  44. }
  45. }
  46. if (drainedCount < N) {
  47. logger.log('All clients have been told to reconnectGracefully')
  48. }
  49. }
  50. }