Skip to content

Loading…

WIP server presence heartbeat using redis #52

Closed
wants to merge 5 commits into from

2 participants

@vanchi-zendesk

@zendesk/zendesk-radar
Currently WIP, will add more code to prune presences...

@nherment nherment commented on the diff
core/lib/server_presence.js
@@ -0,0 +1,40 @@
+var Persistence = require('./persistence.js'),
+ logging = require('minilog')('server_presence');
+
+var radarServerExpiry = 15*1000,
+ serverPresenceId, port, heartbeat,

my 2cts is that we've been bit by using statically defined variables (serverPresenceId, port, heartbeat) in a node file except when it's a constant like radarServerExpiry is.

The alternative is to use a prototyped constructor.

sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@vanchi-zendesk

closed in favor of #85

@vanchi-zendesk vanchi-zendesk deleted the vanchi/presence_pruning branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Showing with 51 additions and 3 deletions.
  1. +1 −0 core/index.js
  2. +7 −3 core/lib/persistence.js
  3. +40 −0 core/lib/server_presence.js
  4. +3 −0 server/server.js
View
1 core/index.js
@@ -5,6 +5,7 @@ var Resource = require('./lib/resource.js'),
module.exports = {
Persistence: require('./lib/persistence.js'),
+ ServerPresence: require('./lib/server_presence.js'),
Type: require('./lib/type.js'),
Map: require('./lib/map.js'),
RemoteManager: require('./lib/resources/presence/remote_manager'),
View
10 core/lib/persistence.js
@@ -36,7 +36,7 @@ function sentinelConnect(sentinelPort, sentinelHost, masterName, redisAuth) {
Persistence.connect = function(done) {
if(client_connected && subscriber_connected) {
- done(); //already connected
+ if(done) done(); //already connected
return;
}
//create a client (read/write)
@@ -70,7 +70,7 @@ Persistence.connect = function(done) {
if(configuration.db) {
client.select(configuration.db, done);
} else {
- done();
+ if(done) done();
}
}
});
@@ -80,7 +80,7 @@ Persistence.connect = function(done) {
subscriber.once('ready', function() {
subscriber_connected = true;
if(client_connected && subscriber_connected) {
- done();
+ if(done) done();
}
});
}
@@ -141,6 +141,10 @@ Persistence.applyPolicy = function(multi, key, policy) {
}
};
+Persistence.exists = function(key, callback) {
+ redis().exists(key, callback);
+};
+
Persistence.readOrderedWithScores = function(key, policy, callback) {
var multi = redis().multi();
View
40 core/lib/server_presence.js
@@ -0,0 +1,40 @@
+var Persistence = require('./persistence.js'),
+ logging = require('minilog')('server_presence');
+
+var radarServerExpiry = 15*1000,
+ serverPresenceId, port, heartbeat,

my 2cts is that we've been bit by using statically defined variables (serverPresenceId, port, heartbeat) in a node file except when it's a constant like radarServerExpiry is.

The alternative is to use a prototyped constructor.

sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ prefix = 'radar_server_presence:/';
+
+function keepAlive() {
+ var scope = prefix + getServerPresenceId();
+
+ logging.info("keep-alive ", scope, new Date());
+ Persistence.persistHash(scope, 'last_seen_at', Date.now());
+ Persistence.expire(scope, 2*radarServerExpiry/1000);
+}
+
+function getServerPresenceId() {
+ if(!serverPresenceId) {
+ serverPresenceId = require('os').hostname() + '/';
+ serverPresenceId += port + '/';
+ serverPresenceId += Date.now(); //Changes every restart
+ logging.debug("Got new serverPresenceId: ",serverPresenceId);
+ }
+ return serverPresenceId;
+}
+
+function fetchServerPresence(id, callback) {
+ Persistence.exists(prefix+id, callback);
+}
+
+module.exports = {
+ getServerPresenceId: getServerPresenceId,
+ setup: function(config_port) {
+ logging.info("Setting up keep-alive");
+ port = config_port;
+ keepAlive();
+ heartbeat = setInterval(keepAlive, radarServerExpiry);
+ },
+ fetchServerPresence: fetchServerPresence,
+ heartbeat: heartbeat
+}
View
3 server/server.js
@@ -4,6 +4,7 @@ var redis = require('redis'),
logging = require('minilog')('server'),
hostname = require('os').hostname(),
Audit = require('./audit.js'),
+ ServerPresence = Core.ServerPresence,
DefaultEngineIO = require('engine.io');
// Parse JSON
@@ -53,6 +54,8 @@ Server.prototype._setup = function(http_server, configuration) {
this.server = engine.attach(http_server, engineConf);
this.server.on('connection', this.onClientConnection.bind(this));
+ ServerPresence.setup(configuration.port);
+
setInterval(Audit.totals, 60 * 1000); // each minute
logging.debug('#server_start ' + new Date().toString());
Something went wrong with that request. Please try again.