aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_bosh.lua
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2015-12-07 19:44:08 +0100
committerKim Alvefur <zash@zash.se>2015-12-07 19:44:08 +0100
commit3918569c79e5463b5084204f58b1e1849afd6039 (patch)
treeef52d93ef228704a74adecac386b865524c92031 /plugins/mod_bosh.lua
parenta6215475087bab66b80db99e23a530f5652d69d4 (diff)
downloadprosody-3918569c79e5463b5084204f58b1e1849afd6039.tar.gz
prosody-3918569c79e5463b5084204f58b1e1849afd6039.zip
mod_bosh: Instead of a global once-per-second timer add a timer for each session when needed
Diffstat (limited to 'plugins/mod_bosh.lua')
-rw-r--r--plugins/mod_bosh.lua79
1 files changed, 32 insertions, 47 deletions
diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua
index 9e8354fe..52974f39 100644
--- a/plugins/mod_bosh.lua
+++ b/plugins/mod_bosh.lua
@@ -63,13 +63,11 @@ local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat;
local os_time = os.time;
-- All sessions, and sessions that have no requests open
-local sessions, inactive_sessions = module:shared("sessions", "inactive_sessions");
+local sessions = module:shared("sessions");
-- Used to respond to idle sessions (those with waiting requests)
-local waiting_requests = module:shared("waiting_requests");
function on_destroy_request(request)
log("debug", "Request destroyed: %s", tostring(request));
- waiting_requests[request] = nil;
local session = sessions[request.context.sid];
if session then
local requests = session.requests;
@@ -83,9 +81,24 @@ function on_destroy_request(request)
-- If this session now has no requests open, mark it as inactive
local max_inactive = session.bosh_max_inactive;
if max_inactive and #requests == 0 then
- inactive_sessions[session] = os_time() + max_inactive;
+ if session.inactive_timer then
+ session.inactive_timer:stop();
+ end
+ session.inactive_timer = module:add_timer(max_inactive, check_inactive, session, request.context,
+ "BOSH client silent for over "..max_inactive.." seconds");
(session.log or log)("debug", "BOSH session marked as inactive (for %ds)", max_inactive);
end
+ if session.bosh_wait_timer then
+ session.bosh_wait_timer:stop();
+ session.bosh_wait_timer = nil;
+ end
+ end
+end
+
+function check_inactive(now, session, context, reason)
+ if not sessions.destroyed then
+ sessions[context.sid] = nil;
+ sm_destroy_session(session, reason);
end
end
@@ -119,7 +132,7 @@ function handle_POST(event)
local headers = response.headers;
headers.content_type = "text/xml; charset=utf-8";
- if cross_domain and event.request.headers.origin then
+ if cross_domain and request.headers.origin then
set_cross_domain_headers(response);
end
@@ -140,8 +153,14 @@ function handle_POST(event)
if session then
-- Session was marked as inactive, since we have
-- a request open now, unmark it
- if inactive_sessions[session] and #session.requests > 0 then
- inactive_sessions[session] = nil;
+ if session.inactive_timer and #session.requests > 0 then
+ session.inactive_timer:stop();
+ session.inactive_timer = nil;
+ end
+
+ if session.bosh_wait_timer then
+ session.bosh_wait_timer:stop();
+ session.bosh_wait_timer = nil;
end
local r = session.requests;
@@ -170,7 +189,7 @@ function handle_POST(event)
-- We're keeping this request open, to respond later
log("debug", "Have nothing to say, so leaving request unanswered for now");
if session.bosh_wait then
- waiting_requests[response] = os_time() + session.bosh_wait;
+ session.bosh_wait_timer = module:add_timer(session.bosh_wait, after_bosh_wait, request, session)
end
end
@@ -186,6 +205,11 @@ function handle_POST(event)
return 400;
end
+function after_bosh_wait(now, request, session)
+ if request.conn then
+ session.send("");
+ end
+end
local function bosh_reset_stream(session) session.notopen = true; end
@@ -225,7 +249,6 @@ local function bosh_close_stream(session, reason)
held_request:send(response_body);
end
sessions[session.sid] = nil;
- inactive_sessions[session] = nil;
sm_destroy_session(session);
end
@@ -407,44 +430,6 @@ function stream_callbacks.error(context, error)
end
end
-local dead_sessions = module:shared("dead_sessions");
-function on_timer()
- -- log("debug", "Checking for requests soon to timeout...");
- -- Identify requests timing out within the next few seconds
- local now = os_time() + 3;
- for request, reply_before in pairs(waiting_requests) do
- if reply_before <= now then
- log("debug", "%s was soon to timeout (at %d, now %d), sending empty response", tostring(request), reply_before, now);
- -- Send empty response to let the
- -- client know we're still here
- if request.conn then
- sessions[request.context.sid].send("");
- end
- end
- end
-
- now = now - 3;
- local n_dead_sessions = 0;
- for session, close_after in pairs(inactive_sessions) do
- if close_after < now then
- (session.log or log)("debug", "BOSH client inactive too long, destroying session at %d", now);
- sessions[session.sid] = nil;
- inactive_sessions[session] = nil;
- n_dead_sessions = n_dead_sessions + 1;
- dead_sessions[n_dead_sessions] = session;
- end
- end
-
- for i=1,n_dead_sessions do
- local session = dead_sessions[i];
- dead_sessions[i] = nil;
- sm_destroy_session(session, "BOSH client silent for over "..session.bosh_max_inactive.." seconds");
- end
- return 1;
-end
-module:add_timer(1, on_timer);
-
-
local GET_response = {
headers = {
content_type = "text/html";