Skip to content

Commit

Permalink
mod_base: Added connection test page
Browse files Browse the repository at this point in the history
  • Loading branch information
mmzeeman committed Nov 24, 2015
1 parent 7c7e210 commit b0f8c5e
Show file tree
Hide file tree
Showing 6 changed files with 389 additions and 0 deletions.
79 changes: 79 additions & 0 deletions modules/mod_base/controllers/controller_connection_test.erl
@@ -0,0 +1,79 @@
%% @author Maas-Maarten Zeeman <mmzeeman@xs4all.nl>
%% @copyright 2015 Maas-Maarten Zeeman
%% @doc Zotonic stream connection tester.

%% Copyright 2015 Maas-Maarten Zeeman
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.


-module(controller_connection_test).
-author("Maas-Maarten Zeeman <mmzeeman@xs4all.nl>").

-export([
init/1,
service_available/2,
charsets_provided/2,
content_types_provided/2,
is_authorized/2,
provide_content/2
]).

-export([
event/2
]).

-include_lib("controller_webmachine_helper.hrl").
-include_lib("include/zotonic.hrl").

-define(DELEGATE(Fun, Module), Fun(ReqData, Args) -> Module:Fun(ReqData, Args)).

init(DispatchArgs) ->
{ok, DispatchArgs}.

service_available(ReqData, DispatchArgs) when is_list(DispatchArgs) ->
Context = z_context:new(ReqData, ?MODULE),
Context1 = z_context:set(DispatchArgs, Context),
Context2 = z_context:continue_session(Context1),
z_context:lager_md(Context2),
?WM_REPLY(true, Context2).


?DELEGATE(charsets_provided, controller_template).
?DELEGATE(content_types_provided, controller_template).
?DELEGATE(is_authorized, controller_template).
?DELEGATE(provide_content, controller_template).


%%
%% Events
%%

event(#postback{message={session_info, []}, target=TargetId}, Context) ->
Vars = [{session_id, z_session:session_id(Context)}],

Pages = lists:reverse(z_session:get_pages(Context)),

AttachStates = [z_session_page:get_attach_state(Pid) || Pid <- Pages],
PageIds = [z_session_page:page_id(Pid) || Pid <- Pages],
Combi = lists:zip(PageIds, AttachStates),

Vars1 = [{pages, Combi} | Vars],

z_render:update(TargetId, #render{template="_session_info.tpl", vars=Vars1}, Context).



%%
%% Helpers
%%
3 changes: 3 additions & 0 deletions modules/mod_base/dispatch/dispatch
Expand Up @@ -19,6 +19,9 @@
%% Used to get page unload beacons from open pages.
{unload_beacon, ["beacon"], controller_unload_beacon, [{ssl, any}, {no_session, true}]},

%% Test page for connection tests
{connection_test, ["connection-test"], controller_connection_test, [{ssl, any}, {template, "connection_test.tpl"}]},

%% The id controller redirects depending on the accept header sent by the user agent.
{id, ["id", id], controller_id, [ {ssl, any} ]},

Expand Down
10 changes: 10 additions & 0 deletions modules/mod_base/lib/js/apps/zotonic-1.0.js
Expand Up @@ -1021,6 +1021,11 @@ function z_stream_restart()
}
}

function z_stream_is_connected()
{
return z_websocket_is_connected() || z_comet_is_connected();
}

function z_comet_start()
{
z_comet_poll_ajax();
Expand Down Expand Up @@ -1076,6 +1081,11 @@ function z_comet_poll_ajax()
}


function z_comet_is_connected()
{
return z_comet && z_comet.readyState != 0;
}

function z_timeout_comet_poll_ajax(timeout)
{
setTimeout(function() {
Expand Down
104 changes: 104 additions & 0 deletions modules/mod_base/lib/js/modules/http_ping.js
@@ -0,0 +1,104 @@
/* HTTP Ping
@package: Channel.me 2015
@Author: MM Zeeman <mmzeeman@xs4all.nl>
Copyright 2015 Maas-Maarten Zeeman
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
* Inserts invisible img tags in the body.
* Tries to load the src, when the onload or onerror are triggered it means
* that the resource was loadable. This is counted as a success.
*/

function http_ping(url, ping_interval) {
var ping_tries = 0;
var ping_errors = 0;
var ping_success = 0;

var ping_latency = 0;
var ping_latency_total = 0;

var ping_latency_min = ping_interval;
var ping_latency_max = 0;

var current_ping;

function ping() {
if(current_ping) {
document.body.removeChild(current_ping);
ping_errors += 1;

current_ping.onload = undefined;
current_ping.onerror = undefined;
current_ping.src = ""; /* cancel loading */
current_ping = undefined;
}

function responded() {
ping_latency = Date.now() - start_time;
ping_latency_total += ping_latency;
ping_success += 1;

ping_latency_max = Math.max(ping_latency, ping_latency_max);
ping_latency_min = Math.min(ping_latency, ping_latency_min);

if(current_ping) {
document.body.removeChild(current_ping);
current_ping = undefined;
}
}

current_ping = document.createElement("img");
current_ping.onload = responded;
current_ping.onerror = responded;
current_ping.src = url;
current_ping.style.display = "none";

document.body.appendChild(current_ping);
var start_time = Date.now();

ping_tries += 1;
};

function loss() {
if(ping_success)
return (ping_errors / ping_success) * 100;

if(ping_errors)
return 100.0;

return 0.0;
}

this.info = function() {
return {
url: url,
tries: ping_tries,
success: ping_success,
errors: ping_errors,
loss: loss(),
latency: ping_latency,
avg_latency: ping_success?(ping_latency_total/ping_success):0,
min_latency: ping_latency_min,
max_latency: ping_latency_max
}
}

ping();
setInterval(ping, ping_interval?ping_interval:1000);
}
19 changes: 19 additions & 0 deletions modules/mod_base/templates/_session_info.tpl
@@ -0,0 +1,19 @@
<dl class="dl-horizontal">
<dt>{_ Session Id _}</dt>
<dd>{{ session_id }}</dd>

<dt>{_ # Pages _}<dt>
<dd>{{ pages | length }}</dd>
</dl>


<table class="table table-bordered">
<thead>
<tr><th >{_ Page Id _}</th><th >{_ Status _}</th></tr>
</thead>
<tbody>
{% for page_id, state in pages %}
<tr><td>{{ page_id }}</td><td>{{ state | pprint }}</td></tr>
{% endfor %}
</tbody>
</table>

0 comments on commit b0f8c5e

Please sign in to comment.