index.coffee 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. _ = require("underscore")
  2. module.exports = RedisSharelatex =
  3. createClient: (opts = {port: 6379, host: "localhost"})->
  4. if !opts.retry_max_delay?
  5. opts.retry_max_delay = 5000 # ms
  6. if opts.password?
  7. opts.auth_pass = opts.password
  8. delete opts.password
  9. if opts.endpoints?
  10. standardOpts = _.clone(opts)
  11. delete standardOpts.endpoints
  12. delete standardOpts.masterName
  13. client = require("redis-sentinel").createClient opts.endpoints, opts.masterName, standardOpts
  14. else
  15. standardOpts = _.clone(opts)
  16. delete standardOpts.port
  17. delete standardOpts.host
  18. client = require("redis").createClient opts.port, opts.host, standardOpts
  19. return client
  20. createRobustSubscriptionClient: (opts, heartbeatOpts = {}) ->
  21. sub = RedisSharelatex.createClient(opts)
  22. pub = RedisSharelatex.createClient(opts)
  23. heartbeatInterval = heartbeatOpts.heartbeat_interval or 1000 #ms
  24. reconnectAfter = heartbeatOpts.reconnect_after or 5000 #ms
  25. id = require("crypto").randomBytes(16).toString("hex")
  26. heartbeatChannel = "heartbeat-#{id}"
  27. lastHeartbeat = Date.now()
  28. sub.subscribe heartbeatChannel, (error) ->
  29. if error?
  30. console.error "ERROR: failed to subscribe to #{heartbeatChannel} channel", error
  31. sub.on "message", (channel, message) ->
  32. if channel == heartbeatChannel
  33. lastHeartbeat = Date.now()
  34. reconnectIfInactive = () ->
  35. timeSinceLastHeartBeat = Date.now() - lastHeartbeat
  36. if timeSinceLastHeartBeat > reconnectAfter
  37. console.warn "No heartbeat for #{timeSinceLastHeartBeat}ms, reconnecting"
  38. sub.connection_gone("no heartbeat for #{timeSinceLastHeartBeat}ms")
  39. setInterval () ->
  40. pub.publish heartbeatChannel, "PING"
  41. reconnectIfInactive()
  42. , heartbeatInterval
  43. return sub