From 720f24427ab87b20da796f448e0686802fcb6c0b Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 2 May 2017 15:51:17 +0100 Subject: [PATCH 1/2] Use new redis-sharelatex with support for cluster --- services/real-time/app.coffee | 12 ++++--- .../app/coffee/ConnectedUsersManager.coffee | 36 +++++++++---------- .../coffee/DocumentUpdaterController.coffee | 2 +- .../app/coffee/DocumentUpdaterManager.coffee | 6 ++-- .../app/coffee/WebsocketLoadBalancer.coffee | 4 +-- .../real-time/config/settings.defaults.coffee | 12 ++++++- services/real-time/package.json | 2 +- .../coffee/ConnectedUsersManagerTests.coffee | 5 ++- .../DocumentUpdaterControllerTests.coffee | 9 +++-- .../coffee/DocumentUpdaterManagerTests.coffee | 4 ++- .../coffee/WebsocketLoadBalancerTests.coffee | 4 +-- 11 files changed, 56 insertions(+), 40 deletions(-) diff --git a/services/real-time/app.coffee b/services/real-time/app.coffee index e4d1fd5446..578520296d 100644 --- a/services/real-time/app.coffee +++ b/services/real-time/app.coffee @@ -51,12 +51,14 @@ io.configure -> app.get "/status", (req, res, next) -> 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) -> - if redisCheck.isAlive() - res.send 200 - else - res.send 500 + rclient.healthCheck (error) -> + if error? + logger.err {err: error}, "failed redis health check" + res.sendStatus 500 + else + res.sendStatus 200 Router = require "./app/js/Router" Router.configure(app, io, sessionSockets) diff --git a/services/real-time/app/coffee/ConnectedUsersManager.coffee b/services/real-time/app/coffee/ConnectedUsersManager.coffee index fa7e366ad8..46454471ba 100644 --- a/services/real-time/app/coffee/ConnectedUsersManager.coffee +++ b/services/real-time/app/coffee/ConnectedUsersManager.coffee @@ -2,8 +2,8 @@ async = require("async") Settings = require('settings-sharelatex') logger = require("logger-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_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 -buildProjectSetKey = (project_id)-> return "clients_in_project:#{project_id}" -buildUserKey = (project_id, client_id)-> return "connected_user:#{project_id}:#{client_id}" - - module.exports = # 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.sadd buildProjectSetKey(project_id), client_id - multi.expire buildProjectSetKey(project_id), FOUR_DAYS_IN_S + multi.sadd Keys.clientsInProject({project_id}), client_id + multi.expire Keys.clientsInProject({project_id}), FOUR_DAYS_IN_S - multi.hset buildUserKey(project_id, client_id), "last_updated_at", Date.now() - multi.hset buildUserKey(project_id, client_id), "user_id", user._id - multi.hset buildUserKey(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 buildUserKey(project_id, client_id), "email", user.email or "" + multi.hset Keys.connectedUser({project_id, client_id}), "last_updated_at", Date.now() + multi.hset Keys.connectedUser({project_id, client_id}), "user_id", user._id + multi.hset Keys.connectedUser({project_id, client_id}), "first_name", user.first_name or "" + multi.hset Keys.connectedUser({project_id, client_id}), "last_name", user.last_name or "" + multi.hset Keys.connectedUser({project_id, client_id}), "email", user.email or "" if cursorData? - multi.hset buildUserKey(project_id, client_id), "cursorData", JSON.stringify(cursorData) - multi.expire buildUserKey(project_id, client_id), USER_TIMEOUT_IN_S + multi.hset Keys.connectedUser({project_id, client_id}), "cursorData", JSON.stringify(cursorData) + multi.expire Keys.connectedUser({project_id, client_id}), USER_TIMEOUT_IN_S multi.exec (err)-> if err? @@ -46,14 +42,14 @@ module.exports = markUserAsDisconnected: (project_id, client_id, callback)-> logger.log project_id:project_id, client_id:client_id, "marking user as disconnected" multi = rclient.multi() - multi.srem buildProjectSetKey(project_id), client_id - multi.expire buildProjectSetKey(project_id), FOUR_DAYS_IN_S - multi.del buildUserKey(project_id, client_id) + multi.srem Keys.clientsInProject({project_id}), client_id + multi.expire Keys.clientsInProject({project_id}), FOUR_DAYS_IN_S + multi.del Keys.connectedUser({project_id, client_id}) multi.exec 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? result = connected : false @@ -71,7 +67,7 @@ module.exports = getConnectedUsers: (project_id, callback)-> self = @ - rclient.smembers buildProjectSetKey(project_id), (err, results)-> + rclient.smembers Keys.clientsInProject({project_id}), (err, results)-> return callback(err) if err? jobs = results.map (client_id)-> (cb)-> diff --git a/services/real-time/app/coffee/DocumentUpdaterController.coffee b/services/real-time/app/coffee/DocumentUpdaterController.coffee index 230eb14f98..01a8732a2a 100644 --- a/services/real-time/app/coffee/DocumentUpdaterController.coffee +++ b/services/real-time/app/coffee/DocumentUpdaterController.coffee @@ -1,7 +1,7 @@ logger = require "logger-sharelatex" settings = require 'settings-sharelatex' redis = require("redis-sharelatex") -rclient = redis.createClient(settings.redis.web) +rclient = redis.createClient(settings.redis.documentupdater) SafeJsonParse = require "./SafeJsonParse" MESSAGE_SIZE_LOG_LIMIT = 1024 * 1024 # 1Mb diff --git a/services/real-time/app/coffee/DocumentUpdaterManager.coffee b/services/real-time/app/coffee/DocumentUpdaterManager.coffee index 9d47a3ffc1..0c8d864ce8 100644 --- a/services/real-time/app/coffee/DocumentUpdaterManager.coffee +++ b/services/real-time/app/coffee/DocumentUpdaterManager.coffee @@ -3,8 +3,8 @@ logger = require "logger-sharelatex" settings = require "settings-sharelatex" metrics = require("metrics-sharelatex") -redis = require("redis-sharelatex") -rclient = redis.createClient(settings.redis.web) +rclient = require("redis-sharelatex").createClient(settings.redis.documentupdater) +Keys = settings.redis.documentupdater.key_schema module.exports = DocumentUpdaterManager = getDocument: (project_id, doc_id, fromVersion, callback = (error, exists, doclines, version) ->) -> @@ -56,7 +56,7 @@ module.exports = DocumentUpdaterManager = jsonChange = JSON.stringify change doc_key = "#{project_id}:#{doc_id}" multi = rclient.multi() - multi.rpush "PendingUpdates:#{doc_id}", jsonChange + multi.rpush Keys.pendingUpdates({doc_id}), jsonChange multi.sadd "DocsWithPendingUpdates", doc_key multi.rpush "pending-updates-list", doc_key multi.exec (error) -> diff --git a/services/real-time/app/coffee/WebsocketLoadBalancer.coffee b/services/real-time/app/coffee/WebsocketLoadBalancer.coffee index d346c41107..56ce8e5d30 100644 --- a/services/real-time/app/coffee/WebsocketLoadBalancer.coffee +++ b/services/real-time/app/coffee/WebsocketLoadBalancer.coffee @@ -2,8 +2,8 @@ Settings = require 'settings-sharelatex' logger = require 'logger-sharelatex' redis = require("redis-sharelatex") SafeJsonParse = require "./SafeJsonParse" -rclientPub = redis.createClient(Settings.redis.web) -rclientSub = redis.createClient(Settings.redis.web) +rclientPub = redis.createClient(Settings.redis.realtime) +rclientSub = redis.createClient(Settings.redis.realtime) module.exports = WebsocketLoadBalancer = rclientPub: rclientPub diff --git a/services/real-time/config/settings.defaults.coffee b/services/real-time/config/settings.defaults.coffee index 5e6a3691ab..b8fe111b98 100644 --- a/services/real-time/config/settings.defaults.coffee +++ b/services/real-time/config/settings.defaults.coffee @@ -1,9 +1,19 @@ module.exports = redis: - web: + realtime: host: "localhost" port: "6379" 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: realTime: diff --git a/services/real-time/package.json b/services/real-time/package.json index 4f4034fe28..fa67f0511e 100644 --- a/services/real-time/package.json +++ b/services/real-time/package.json @@ -18,7 +18,7 @@ "ioredis": "^2.4.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", - "redis-sharelatex": "0.0.9", + "redis-sharelatex": "git+https://github.com/sharelatex/redis-sharelatex.git#v1.0.0", "request": "~2.34.0", "session.socket.io": "^0.1.6", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", diff --git a/services/real-time/test/unit/coffee/ConnectedUsersManagerTests.coffee b/services/real-time/test/unit/coffee/ConnectedUsersManagerTests.coffee index 982f4a170f..9f77cb0e8b 100644 --- a/services/real-time/test/unit/coffee/ConnectedUsersManagerTests.coffee +++ b/services/real-time/test/unit/coffee/ConnectedUsersManagerTests.coffee @@ -15,7 +15,10 @@ describe "ConnectedUsersManager", -> @settings = 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 = auth:-> setex:sinon.stub() diff --git a/services/real-time/test/unit/coffee/DocumentUpdaterControllerTests.coffee b/services/real-time/test/unit/coffee/DocumentUpdaterControllerTests.coffee index 8673b12b41..cb77a11513 100644 --- a/services/real-time/test/unit/coffee/DocumentUpdaterControllerTests.coffee +++ b/services/real-time/test/unit/coffee/DocumentUpdaterControllerTests.coffee @@ -13,10 +13,13 @@ describe "DocumentUpdaterController", -> @EditorUpdatesController = SandboxedModule.require modulePath, requires: "logger-sharelatex": @logger = { error: sinon.stub(), log: sinon.stub() } "settings-sharelatex": @settings = - redis: web: {} + redis: + documentupdater: + key_schema: + pendingUpdates: ({doc_id}) -> "PendingUpdates:#{doc_id}" "redis-sharelatex" : - createClient: ()=> - @rclient = {auth:->} + createClient: () => + @rclient = {} "./SafeJsonParse": @SafeJsonParse = parse: (data, cb) => cb null, JSON.parse(data) diff --git a/services/real-time/test/unit/coffee/DocumentUpdaterManagerTests.coffee b/services/real-time/test/unit/coffee/DocumentUpdaterManagerTests.coffee index fbf44aeffe..c693880e39 100644 --- a/services/real-time/test/unit/coffee/DocumentUpdaterManagerTests.coffee +++ b/services/real-time/test/unit/coffee/DocumentUpdaterManagerTests.coffee @@ -12,7 +12,9 @@ describe 'DocumentUpdaterManager', -> @version = 42 @settings = apis: documentupdater: url: "http://doc-updater.example.com" - redis: web: {} + redis: documentupdater: + key_schema: + pendingUpdates: ({doc_id}) -> "PendingUpdates:#{doc_id}" @rclient = {auth:->} @DocumentUpdaterManager = SandboxedModule.require modulePath, requires: diff --git a/services/real-time/test/unit/coffee/WebsocketLoadBalancerTests.coffee b/services/real-time/test/unit/coffee/WebsocketLoadBalancerTests.coffee index 07afe988ab..5cae81a31d 100644 --- a/services/real-time/test/unit/coffee/WebsocketLoadBalancerTests.coffee +++ b/services/real-time/test/unit/coffee/WebsocketLoadBalancerTests.coffee @@ -5,10 +5,10 @@ modulePath = require('path').join __dirname, '../../../app/js/WebsocketLoadBalan describe "WebsocketLoadBalancer", -> beforeEach -> + @rclient = {} @WebsocketLoadBalancer = SandboxedModule.require modulePath, requires: "redis-sharelatex": - createClient: () -> - auth:-> + createClient: () => @rclient "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() } "./SafeJsonParse": @SafeJsonParse = parse: (data, cb) => cb null, JSON.parse(data) From d04be1c000d5d399d31525c2604e87609741cd82 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 9 May 2017 17:09:00 +0100 Subject: [PATCH 2/2] Update redis-sharelatex --- services/real-time/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/real-time/package.json b/services/real-time/package.json index fa67f0511e..4b3de3d5f3 100644 --- a/services/real-time/package.json +++ b/services/real-time/package.json @@ -18,7 +18,7 @@ "ioredis": "^2.4.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", - "redis-sharelatex": "git+https://github.com/sharelatex/redis-sharelatex.git#v1.0.0", + "redis-sharelatex": "git+https://github.com/sharelatex/redis-sharelatex.git#v1.0.2", "request": "~2.34.0", "session.socket.io": "^0.1.6", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0",