diff --git a/apiserver/api/internal.js b/apiserver/api/internal.js index 6c968e9..2e3ffcb 100644 --- a/apiserver/api/internal.js +++ b/apiserver/api/internal.js @@ -139,5 +139,14 @@ module.exports = { cb(); } + }, + + // Increment an app's heartbeat by 1 + incrementHeartbeat: { + routePath : '/internal/incrementHeartbeat', + payloadSource: 'body', + method: 'POST', + okayCode: 200, + errorCode: 404 } }; diff --git a/postgres/openruko_api/functions/increment_heartbeat.pgsql b/postgres/openruko_api/functions/increment_heartbeat.pgsql new file mode 100644 index 0000000..ba2da38 --- /dev/null +++ b/postgres/openruko_api/functions/increment_heartbeat.pgsql @@ -0,0 +1,33 @@ +CREATE OR REPLACE FUNCTION increment_heartbeat(p_instance_id text) +RETURNS SETOF integer AS +$BODY$ +DECLARE + v_heartbeats integer; + v_app_id integer; +BEGIN + + SELECT app_id FROM instance WHERE id = p_instance_id + LIMIT 1 + INTO v_app_id; + + SELECT heartbeats FROM app WHERE id = v_app_id + LIMIT 1 + INTO v_heartbeats; + + IF v_heartbeats IS NOT null THEN + UPDATE app + SET heartbeats = heartbeats + 1 + WHERE id = v_app_id; + ELSE + UPDATE app + SET heartbeats = 1 + WHERE id = v_app_id; + END IF; + + RETURN QUERY SELECT app.heartbeats FROM app WHERE id = v_app_id; + +END; +$BODY$ +LANGUAGE plpgsql VOLATILE +-- vim: set filetype=pgsql : + diff --git a/postgres/openruko_data/tables/0.1.1.do.app.pgsql b/postgres/openruko_data/tables/0.1.1.do.app.pgsql new file mode 100644 index 0000000..ae04395 --- /dev/null +++ b/postgres/openruko_data/tables/0.1.1.do.app.pgsql @@ -0,0 +1 @@ +ALTER TABLE app ADD COLUMN heartbeats integer; \ No newline at end of file diff --git a/test/internal-provisionJob.js b/test/internal-provisionJob.js index ffdb4cc..2d98135 100644 --- a/test/internal-provisionJob.js +++ b/test/internal-provisionJob.js @@ -226,6 +226,20 @@ describe('internal provisionJob', function(){ }, 30); }); + it('it should handle heartbeats and increment an app\'s total heartbeats', function(done){ + var instance_id; + preReceiveMock('myApp', function(){ + dynohostMock.getJobs(function(err, data){ + if(err) return done(err); + instance_id = data[0].instance_id; + dynohostMock.incrementHeartbeat(instance_id, function(err, body){ + expect(body.rows[0].increment_heartbeat).to.be.greaterThan(0); + done(); + }); + }); + }); + }) + describe('when updating the repo', function(){ beforeEach(function(done){ preReceiveMock('myApp', done); diff --git a/test/mock/dynohost.js b/test/mock/dynohost.js index a8cd9b6..95f552f 100644 --- a/test/mock/dynohost.js +++ b/test/mock/dynohost.js @@ -15,6 +15,17 @@ exports.updateState = function(appId, dynoId, instanceId, state, cb){ }, cb); }; +exports.incrementHeartbeat = function(instanceId, cb){ + request.post({ + url: base + '/internal/incrementHeartbeat', + json: { + instanceId: instanceId + } + }, function(err, resp, body){ + cb(err, body); + }); +}; + exports.getJobs = function(cb){ request({ url: base + '/internal/getjobs',