SessionLatency class start.

This commit is contained in:
Jonathon Wilson 2012-11-27 19:29:46 -07:00
parent 9e5eb36196
commit 2cf4794fd0
5 changed files with 217 additions and 2 deletions

View File

@ -3,12 +3,15 @@
context.JK = context.JK || {};
context.JK.FindSessionScreen = function(app) {
var logger = context.JK.logger;
var sessionLatency;
function loadSessions() {
$.ajax({
type: "GET",
url: "/api/sessions"
}).done(renderSessions);
url: "/api/sessions",
// TODO: Change to buildLatencyMap
success: renderSessions
});
}
function renderSessions(response) {
@ -44,7 +47,14 @@
$('#findSession-tableBody').on("click", '[action="delete"]', deleteSession);
}
this.afterShow = afterShow;
this.initialize = function() {
if ("jamClient" in context) {
sessionLatency = new context.JK.SessionLatency(jamClient);
} else {
logger.warn("No jamClient available. Session pings will not be performed.");
}
screenBindings = {
'afterShow': afterShow
};

View File

@ -0,0 +1,63 @@
(function(context) {
context.JK = context.JK || {};
context.JK.SessionLatency = function(jamClient) {
var logger = context.JK.logger;
var sessionPingsOut = {};
var clientsToSessions = {};
var sessionLatency = {};
function sessionPings(session) {
$.each(session.participants, function(index, participant) {
var client = { id: participant.client_id };
clientsToSessions[client.id] = session.id;
if (!(session.id in sessionPingsOut)) {
sessionPingsOut[session.id] = 0;
}
sessionPingsOut[session.id]++;
jamClient.testLatency(client, clientPingResponse);
});
}
function clientPingResponse(response) {
var sessionId = clientsToSessions[response.id];
sessionPingsOut[sessionId]--;
updateSessionLatency(sessionId, response);
}
function updateSessionLatency(sessionId, latencyResponse) {
if (!(sessionId in sessionLatency)) {
sessionLatency[sessionId] = {
clientLatencies: {},
averageLatency: 0
};
}
var sl = sessionLatency[sessionId];
sl.clientLatencies[latencyResponse.id] = latencyResponse.latency;
sl.averageLatency = latencyAverage(sl.clientLatencies);
}
function latencyAverage(clientLatencies) {
var total = 0;
var count = 0;
$.each(clientLatencies, function(index, latency) {
total += latency;
count++;
});
return total/count;
}
function sessionInfo(sessionId) {
return sessionLatency[sessionId];
}
this.sessionPings = sessionPings;
this.sessionInfo = sessionInfo;
return this;
};
})(window);

View File

@ -0,0 +1,52 @@
(function(context,$) {
describe("FindSession", function() {
var fss;
var ajaxSpy;
var selectors = {
sessions: '#findSession-tableBody'
};
var appFake = {
clientId: '12345',
bindScreen: function(){},
notify: function(){},
ajaxError: function() { console.debug("ajaxError"); }
};
beforeEach(function() {
// Use the actual screen markup
jasmine.getFixtures().fixturesPath = '/app/views/clients';
loadFixtures('_findSession.html.erb');
spyOn(appFake, 'notify');
fss = new context.JK.FindSessionScreen(appFake);
fss.initialize();
});
describe("loadSessions", function() {
beforeEach(function() {
spyOn($, "ajax");
});
it("should query ajax for sessions", function() {
fss.afterShow({});
expect($.ajax).toHaveBeenCalled();
});
});
describe("renderSessions", function() {
beforeEach(function() {
spyOn($, "ajax").andCallFake(function(opts) {
opts.success(TestResponses.getSessions);
});
});
it("should output table rows for sessions", function() {
fss.afterShow({});
expect($(selectors.sessions + ' tr').length).toEqual(1);
});
});
});
})(window,jQuery);

View File

@ -1,4 +1,34 @@
window.TestResponses = {
getSessions: [
{
"id": "1234",
"description": "Hello",
"musician_access": true,
"genres" : [ "classical" ],
"participants": [
{
"client_id": "0f8f7987-29a0-4e5d-a60c-6b23103e3533",
"ip_address":"1.1.1.1",
"user_id" : "02303020402042040", // NOTE THIS WILL BE UNDEFINED (ABSENT) IF THIS CLIENT IS NOT YOUR FRIEND
"tracks" : [
{
"id" : "xxxx",
"instrument_id" : "electric guitar",
"sound" : "mono"
}
]
}
],
"invitations" : [
{
"id" : "3948797598275987",
"sender_id" : "02303020402042040"
}
]
}
],
sessionPost: {
"id": "1234",
"description": "Hello",

View File

@ -0,0 +1,60 @@
(function(context, $) {
describe("SessionLatency", function() {
var sessionLatency; // Instance of SessionLatency class for test
fakeJamClient = {
testLatency: function() {} // Will be overridden by test cases
};
beforeEach(function() {
sessionLatency = new context.JK.SessionLatency(fakeJamClient);
});
describe("SessionPings", function() {
it("should call jamClient.testLatency and compute new average", function() {
var session = {
id: "123",
participants: [ { client_id: "999", ip_address: "1.1.1.1" } ]
};
spyOn(fakeJamClient, "testLatency").andCallFake(function(client, callback) {
callback({id: "999", latency: 35});
});
sessionLatency.sessionPings(session);
expect(fakeJamClient.testLatency).toHaveBeenCalled();
var info = sessionLatency.sessionInfo(session.id);
expect(info.averageLatency).toEqual(35);
});
it("should average multiple client pings", function() {
var session = {
id: "123",
participants: [
{ client_id: "1", ip_address: "1.1.1.1" },
{ client_id: "2", ip_address: "1.1.1.2" },
{ client_id: "3", ip_address: "1.1.1.3" }
]
};
pingResponses = [
{id: "1", latency: 100},
{id: "2", latency: 10},
{id: "3", latency: 10}
];
pingResponseIndex = 0;
spyOn(fakeJamClient, "testLatency").andCallFake(function(client, callback) {
callback(pingResponses[pingResponseIndex]);
pingResponseIndex++;
});
sessionLatency.sessionPings(session);
var info = sessionLatency.sessionInfo(session.id);
expect(info.averageLatency).toEqual(40);
});
});
});
})(window, jQuery);