mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #12 from sharelatex/ja-redis-cluster-refactor
Use new redis-sharelatex with support for cluster
This commit is contained in:
commit
b7a07ea1b7
11 changed files with 56 additions and 40 deletions
|
@ -51,12 +51,14 @@ io.configure ->
|
||||||
app.get "/status", (req, res, next) ->
|
app.get "/status", (req, res, next) ->
|
||||||
res.send "real-time-sharelatex is alive"
|
res.send "real-time-sharelatex is alive"
|
||||||
|
|
||||||
redisCheck = redis.activeHealthCheckRedis(Settings.redis.web)
|
rclient = require("redis-sharelatex").createClient(Settings.redis.realtime)
|
||||||
app.get "/health_check/redis", (req, res, next) ->
|
app.get "/health_check/redis", (req, res, next) ->
|
||||||
if redisCheck.isAlive()
|
rclient.healthCheck (error) ->
|
||||||
res.send 200
|
if error?
|
||||||
|
logger.err {err: error}, "failed redis health check"
|
||||||
|
res.sendStatus 500
|
||||||
else
|
else
|
||||||
res.send 500
|
res.sendStatus 200
|
||||||
|
|
||||||
Router = require "./app/js/Router"
|
Router = require "./app/js/Router"
|
||||||
Router.configure(app, io, sessionSockets)
|
Router.configure(app, io, sessionSockets)
|
||||||
|
|
|
@ -2,8 +2,8 @@ async = require("async")
|
||||||
Settings = require('settings-sharelatex')
|
Settings = require('settings-sharelatex')
|
||||||
logger = require("logger-sharelatex")
|
logger = require("logger-sharelatex")
|
||||||
redis = require("redis-sharelatex")
|
redis = require("redis-sharelatex")
|
||||||
rclient = redis.createClient(Settings.redis.web)
|
rclient = redis.createClient(Settings.redis.realtime)
|
||||||
|
Keys = Settings.redis.realtime.key_schema
|
||||||
|
|
||||||
ONE_HOUR_IN_S = 60 * 60
|
ONE_HOUR_IN_S = 60 * 60
|
||||||
ONE_DAY_IN_S = ONE_HOUR_IN_S * 24
|
ONE_DAY_IN_S = ONE_HOUR_IN_S * 24
|
||||||
|
@ -11,10 +11,6 @@ FOUR_DAYS_IN_S = ONE_DAY_IN_S * 4
|
||||||
|
|
||||||
USER_TIMEOUT_IN_S = ONE_HOUR_IN_S / 4
|
USER_TIMEOUT_IN_S = ONE_HOUR_IN_S / 4
|
||||||
|
|
||||||
buildProjectSetKey = (project_id)-> return "clients_in_project:#{project_id}"
|
|
||||||
buildUserKey = (project_id, client_id)-> return "connected_user:#{project_id}:#{client_id}"
|
|
||||||
|
|
||||||
|
|
||||||
module.exports =
|
module.exports =
|
||||||
|
|
||||||
# Use the same method for when a user connects, and when a user sends a cursor
|
# Use the same method for when a user connects, and when a user sends a cursor
|
||||||
|
@ -25,18 +21,18 @@ module.exports =
|
||||||
|
|
||||||
multi = rclient.multi()
|
multi = rclient.multi()
|
||||||
|
|
||||||
multi.sadd buildProjectSetKey(project_id), client_id
|
multi.sadd Keys.clientsInProject({project_id}), client_id
|
||||||
multi.expire buildProjectSetKey(project_id), FOUR_DAYS_IN_S
|
multi.expire Keys.clientsInProject({project_id}), FOUR_DAYS_IN_S
|
||||||
|
|
||||||
multi.hset buildUserKey(project_id, client_id), "last_updated_at", Date.now()
|
multi.hset Keys.connectedUser({project_id, client_id}), "last_updated_at", Date.now()
|
||||||
multi.hset buildUserKey(project_id, client_id), "user_id", user._id
|
multi.hset Keys.connectedUser({project_id, client_id}), "user_id", user._id
|
||||||
multi.hset buildUserKey(project_id, client_id), "first_name", user.first_name or ""
|
multi.hset Keys.connectedUser({project_id, client_id}), "first_name", user.first_name or ""
|
||||||
multi.hset buildUserKey(project_id, client_id), "last_name", user.last_name or ""
|
multi.hset Keys.connectedUser({project_id, client_id}), "last_name", user.last_name or ""
|
||||||
multi.hset buildUserKey(project_id, client_id), "email", user.email or ""
|
multi.hset Keys.connectedUser({project_id, client_id}), "email", user.email or ""
|
||||||
|
|
||||||
if cursorData?
|
if cursorData?
|
||||||
multi.hset buildUserKey(project_id, client_id), "cursorData", JSON.stringify(cursorData)
|
multi.hset Keys.connectedUser({project_id, client_id}), "cursorData", JSON.stringify(cursorData)
|
||||||
multi.expire buildUserKey(project_id, client_id), USER_TIMEOUT_IN_S
|
multi.expire Keys.connectedUser({project_id, client_id}), USER_TIMEOUT_IN_S
|
||||||
|
|
||||||
multi.exec (err)->
|
multi.exec (err)->
|
||||||
if err?
|
if err?
|
||||||
|
@ -46,14 +42,14 @@ module.exports =
|
||||||
markUserAsDisconnected: (project_id, client_id, callback)->
|
markUserAsDisconnected: (project_id, client_id, callback)->
|
||||||
logger.log project_id:project_id, client_id:client_id, "marking user as disconnected"
|
logger.log project_id:project_id, client_id:client_id, "marking user as disconnected"
|
||||||
multi = rclient.multi()
|
multi = rclient.multi()
|
||||||
multi.srem buildProjectSetKey(project_id), client_id
|
multi.srem Keys.clientsInProject({project_id}), client_id
|
||||||
multi.expire buildProjectSetKey(project_id), FOUR_DAYS_IN_S
|
multi.expire Keys.clientsInProject({project_id}), FOUR_DAYS_IN_S
|
||||||
multi.del buildUserKey(project_id, client_id)
|
multi.del Keys.connectedUser({project_id, client_id})
|
||||||
multi.exec callback
|
multi.exec callback
|
||||||
|
|
||||||
|
|
||||||
_getConnectedUser: (project_id, client_id, callback)->
|
_getConnectedUser: (project_id, client_id, callback)->
|
||||||
rclient.hgetall buildUserKey(project_id, client_id), (err, result)->
|
rclient.hgetall Keys.connectedUser({project_id, client_id}), (err, result)->
|
||||||
if !result?
|
if !result?
|
||||||
result =
|
result =
|
||||||
connected : false
|
connected : false
|
||||||
|
@ -71,7 +67,7 @@ module.exports =
|
||||||
|
|
||||||
getConnectedUsers: (project_id, callback)->
|
getConnectedUsers: (project_id, callback)->
|
||||||
self = @
|
self = @
|
||||||
rclient.smembers buildProjectSetKey(project_id), (err, results)->
|
rclient.smembers Keys.clientsInProject({project_id}), (err, results)->
|
||||||
return callback(err) if err?
|
return callback(err) if err?
|
||||||
jobs = results.map (client_id)->
|
jobs = results.map (client_id)->
|
||||||
(cb)->
|
(cb)->
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
logger = require "logger-sharelatex"
|
logger = require "logger-sharelatex"
|
||||||
settings = require 'settings-sharelatex'
|
settings = require 'settings-sharelatex'
|
||||||
redis = require("redis-sharelatex")
|
redis = require("redis-sharelatex")
|
||||||
rclient = redis.createClient(settings.redis.web)
|
rclient = redis.createClient(settings.redis.documentupdater)
|
||||||
SafeJsonParse = require "./SafeJsonParse"
|
SafeJsonParse = require "./SafeJsonParse"
|
||||||
|
|
||||||
MESSAGE_SIZE_LOG_LIMIT = 1024 * 1024 # 1Mb
|
MESSAGE_SIZE_LOG_LIMIT = 1024 * 1024 # 1Mb
|
||||||
|
|
|
@ -3,8 +3,8 @@ logger = require "logger-sharelatex"
|
||||||
settings = require "settings-sharelatex"
|
settings = require "settings-sharelatex"
|
||||||
metrics = require("metrics-sharelatex")
|
metrics = require("metrics-sharelatex")
|
||||||
|
|
||||||
redis = require("redis-sharelatex")
|
rclient = require("redis-sharelatex").createClient(settings.redis.documentupdater)
|
||||||
rclient = redis.createClient(settings.redis.web)
|
Keys = settings.redis.documentupdater.key_schema
|
||||||
|
|
||||||
module.exports = DocumentUpdaterManager =
|
module.exports = DocumentUpdaterManager =
|
||||||
getDocument: (project_id, doc_id, fromVersion, callback = (error, exists, doclines, version) ->) ->
|
getDocument: (project_id, doc_id, fromVersion, callback = (error, exists, doclines, version) ->) ->
|
||||||
|
@ -56,7 +56,7 @@ module.exports = DocumentUpdaterManager =
|
||||||
jsonChange = JSON.stringify change
|
jsonChange = JSON.stringify change
|
||||||
doc_key = "#{project_id}:#{doc_id}"
|
doc_key = "#{project_id}:#{doc_id}"
|
||||||
multi = rclient.multi()
|
multi = rclient.multi()
|
||||||
multi.rpush "PendingUpdates:#{doc_id}", jsonChange
|
multi.rpush Keys.pendingUpdates({doc_id}), jsonChange
|
||||||
multi.sadd "DocsWithPendingUpdates", doc_key
|
multi.sadd "DocsWithPendingUpdates", doc_key
|
||||||
multi.rpush "pending-updates-list", doc_key
|
multi.rpush "pending-updates-list", doc_key
|
||||||
multi.exec (error) ->
|
multi.exec (error) ->
|
||||||
|
|
|
@ -2,8 +2,8 @@ Settings = require 'settings-sharelatex'
|
||||||
logger = require 'logger-sharelatex'
|
logger = require 'logger-sharelatex'
|
||||||
redis = require("redis-sharelatex")
|
redis = require("redis-sharelatex")
|
||||||
SafeJsonParse = require "./SafeJsonParse"
|
SafeJsonParse = require "./SafeJsonParse"
|
||||||
rclientPub = redis.createClient(Settings.redis.web)
|
rclientPub = redis.createClient(Settings.redis.realtime)
|
||||||
rclientSub = redis.createClient(Settings.redis.web)
|
rclientSub = redis.createClient(Settings.redis.realtime)
|
||||||
|
|
||||||
module.exports = WebsocketLoadBalancer =
|
module.exports = WebsocketLoadBalancer =
|
||||||
rclientPub: rclientPub
|
rclientPub: rclientPub
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
module.exports =
|
module.exports =
|
||||||
redis:
|
redis:
|
||||||
web:
|
realtime:
|
||||||
host: "localhost"
|
host: "localhost"
|
||||||
port: "6379"
|
port: "6379"
|
||||||
password: ""
|
password: ""
|
||||||
|
key_schema:
|
||||||
|
clientsInProject: ({project_id}) -> "clients_in_project:#{project_id}"
|
||||||
|
connectedUser: ({project_id, client_id})-> "connected_user:#{project_id}:#{client_id}"
|
||||||
|
|
||||||
|
documentupdater:
|
||||||
|
host: "localhost"
|
||||||
|
port: "6379"
|
||||||
|
password: ""
|
||||||
|
key_schema:
|
||||||
|
pendingUpdates: ({doc_id}) -> "PendingUpdates:#{doc_id}"
|
||||||
|
|
||||||
internal:
|
internal:
|
||||||
realTime:
|
realTime:
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
"ioredis": "^2.4.0",
|
"ioredis": "^2.4.0",
|
||||||
"logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.1.0",
|
"logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.1.0",
|
||||||
"metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.4.0",
|
"metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.4.0",
|
||||||
"redis-sharelatex": "0.0.9",
|
"redis-sharelatex": "git+https://github.com/sharelatex/redis-sharelatex.git#v1.0.2",
|
||||||
"request": "~2.34.0",
|
"request": "~2.34.0",
|
||||||
"session.socket.io": "^0.1.6",
|
"session.socket.io": "^0.1.6",
|
||||||
"settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0",
|
"settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0",
|
||||||
|
|
|
@ -15,7 +15,10 @@ describe "ConnectedUsersManager", ->
|
||||||
|
|
||||||
@settings =
|
@settings =
|
||||||
redis:
|
redis:
|
||||||
web:{}
|
realtime:
|
||||||
|
key_schema:
|
||||||
|
clientsInProject: ({project_id}) -> "clients_in_project:#{project_id}"
|
||||||
|
connectedUser: ({project_id, client_id})-> "connected_user:#{project_id}:#{client_id}"
|
||||||
@rClient =
|
@rClient =
|
||||||
auth:->
|
auth:->
|
||||||
setex:sinon.stub()
|
setex:sinon.stub()
|
||||||
|
|
|
@ -13,10 +13,13 @@ describe "DocumentUpdaterController", ->
|
||||||
@EditorUpdatesController = SandboxedModule.require modulePath, requires:
|
@EditorUpdatesController = SandboxedModule.require modulePath, requires:
|
||||||
"logger-sharelatex": @logger = { error: sinon.stub(), log: sinon.stub() }
|
"logger-sharelatex": @logger = { error: sinon.stub(), log: sinon.stub() }
|
||||||
"settings-sharelatex": @settings =
|
"settings-sharelatex": @settings =
|
||||||
redis: web: {}
|
redis:
|
||||||
|
documentupdater:
|
||||||
|
key_schema:
|
||||||
|
pendingUpdates: ({doc_id}) -> "PendingUpdates:#{doc_id}"
|
||||||
"redis-sharelatex" :
|
"redis-sharelatex" :
|
||||||
createClient: ()=>
|
createClient: () =>
|
||||||
@rclient = {auth:->}
|
@rclient = {}
|
||||||
"./SafeJsonParse": @SafeJsonParse =
|
"./SafeJsonParse": @SafeJsonParse =
|
||||||
parse: (data, cb) => cb null, JSON.parse(data)
|
parse: (data, cb) => cb null, JSON.parse(data)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@ describe 'DocumentUpdaterManager', ->
|
||||||
@version = 42
|
@version = 42
|
||||||
@settings =
|
@settings =
|
||||||
apis: documentupdater: url: "http://doc-updater.example.com"
|
apis: documentupdater: url: "http://doc-updater.example.com"
|
||||||
redis: web: {}
|
redis: documentupdater:
|
||||||
|
key_schema:
|
||||||
|
pendingUpdates: ({doc_id}) -> "PendingUpdates:#{doc_id}"
|
||||||
@rclient = {auth:->}
|
@rclient = {auth:->}
|
||||||
|
|
||||||
@DocumentUpdaterManager = SandboxedModule.require modulePath, requires:
|
@DocumentUpdaterManager = SandboxedModule.require modulePath, requires:
|
||||||
|
|
|
@ -5,10 +5,10 @@ modulePath = require('path').join __dirname, '../../../app/js/WebsocketLoadBalan
|
||||||
|
|
||||||
describe "WebsocketLoadBalancer", ->
|
describe "WebsocketLoadBalancer", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
|
@rclient = {}
|
||||||
@WebsocketLoadBalancer = SandboxedModule.require modulePath, requires:
|
@WebsocketLoadBalancer = SandboxedModule.require modulePath, requires:
|
||||||
"redis-sharelatex":
|
"redis-sharelatex":
|
||||||
createClient: () ->
|
createClient: () => @rclient
|
||||||
auth:->
|
|
||||||
"logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() }
|
"logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() }
|
||||||
"./SafeJsonParse": @SafeJsonParse =
|
"./SafeJsonParse": @SafeJsonParse =
|
||||||
parse: (data, cb) => cb null, JSON.parse(data)
|
parse: (data, cb) => cb null, JSON.parse(data)
|
||||||
|
|
Loading…
Reference in a new issue