Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit 046fc42c37ff8f520ef0e79a732e2d428d62baaf 0 parents
@jbrisbin authored
6 .gitignore
@@ -0,0 +1,6 @@
+.DS_Store
+data
+deps
+ebin
+*.dump
+log
33 Makefile
@@ -0,0 +1,33 @@
+PACKAGE=cowboy-riak_core-vnode-dispatcher
+DIST_DIR=dist
+EBIN_DIR=ebin
+INCLUDE_DIRS=include
+DEPS_DIR=deps
+DEPS ?= cowboy sockjs basho_stats lager mochiweb poolboy protobuffs riak_core riak_sysmon webmachine
+DEPS_EZ=$(foreach DEP, $(DEPS), $(DEPS_DIR)/$(DEP).ez)
+RABBITMQ_HOME ?= .
+
+all: compile
+
+clean:
+ rm -rf $(DIST_DIR)
+ rm -rf $(EBIN_DIR)
+
+distclean: clean
+ rm -rf $(DEPS_DIR)
+
+package: compile $(DEPS_EZ)
+ rm -f $(DIST_DIR)/$(PACKAGE).ez
+ mkdir -p $(DIST_DIR)/$(PACKAGE)
+ cp -r $(EBIN_DIR) $(DIST_DIR)/$(PACKAGE)
+ $(foreach EXTRA_DIR, $(INCLUDE_DIRS), cp -r $(EXTRA_DIR) $(DIST_DIR)/$(PACKAGE);)
+ (cd $(DIST_DIR); zip -r $(PACKAGE).ez $(PACKAGE))
+
+$(DEPS_DIR):
+ ./rebar get-deps
+
+$(DEPS_EZ):
+ cd $(DEPS_DIR); $(foreach DEP, $(DEPS), zip -r $(DEP).ez $(DEP);)
+
+compile: $(DEPS_DIR)
+ ./rebar compile
114 hello_world1.config
@@ -0,0 +1,114 @@
+%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ft=erlang ts=4 sw=4 et
+[
+ {hello_world, [
+ {web_port, 3000},
+ {master_node, 'helloworld1@localhost'}
+ ]},
+
+ %% Riak Core config
+ {riak_core, [
+ %% Default location of ringstate
+ {ring_state_dir, "./data/ring1"},
+
+ %% http is a list of IP addresses and TCP ports that the Riak
+ %% HTTP interface will bind.
+ %{http, [ {"127.0.0.1", 8098 } ]},
+
+ %% https is a list of IP addresses and TCP ports that the Riak
+ %% HTTPS interface will bind.
+ %{https, [{ "127.0.0.1", 8098 }]},
+
+ %% Default cert and key locations for https can be overridden
+ %% with the ssl config variable, for example:
+ %{ssl, [
+ % {certfile, "./etc/cert.pem"},
+ % {keyfile, "./etc/key.pem"}
+ % ]},
+
+ %% riak_handoff_port is the TCP port that Riak uses for
+ %% intra-cluster data handoff.
+ {handoff_port, 8099 },
+
+ %% To encrypt riak_core intra-cluster data handoff traffic,
+ %% uncomment the following line and edit its path to an
+ %% appropriate certfile and keyfile. (This example uses a
+ %% single file with both items concatenated together.)
+ %{handoff_ssl_options, [{certfile, "/tmp/erlserver.pem"}]},
+
+ %% Platform-specific installation paths (substituted by rebar)
+ {platform_bin_dir, "./bin"},
+ {platform_data_dir, "./data"},
+ {platform_etc_dir, "./etc"},
+ {platform_lib_dir, "./lib"},
+ {platform_log_dir, "./log"}
+ ]},
+
+ %% Lager Config
+ {lager, [
+ %% What handlers to install with what arguments
+ %% The defaults for the logfiles are to rotate the files when
+ %% they reach 10Mb or at midnight, whichever comes first, and keep
+ %% the last 5 rotations. See the lager README for a description of
+ %% the time rotation format:
+ %% https://github.com/basho/lager/blob/master/README.org
+ %%
+ %% If you wish to disable rotation, you can either set the size to 0
+ %% and the rotation time to "", or instead specify a 2-tuple that only
+ %% consists of {Logfile, Level}.
+ {handlers, [
+ {lager_console_backend, info},
+ {lager_file_backend, [
+ {"./log/error.log", error, 10485760, "$D0", 5},
+ {"./log/console.log", info, 10485760, "$D0", 5}
+ ]}
+ ]},
+
+ %% Whether to write a crash log, and where.
+ %% Commented/omitted/undefined means no crash logger.
+ {crash_log, "./log/crash.log"},
+
+ %% Maximum size in bytes of events in the crash log - defaults to 65536
+ {crash_log_msg_size, 65536},
+
+ %% Maximum size of the crash log in bytes, before its rotated, set
+ %% to 0 to disable rotation - default is 0
+ {crash_log_size, 10485760},
+
+ %% What time to rotate the crash log - default is no time
+ %% rotation. See the lager README for a description of this format:
+ %% https://github.com/basho/lager/blob/master/README.org
+ {crash_log_date, "$D0"},
+
+ %% Number of rotated crash logs to keep, 0 means keep only the
+ %% current one - default is 0
+ {crash_log_count, 5},
+
+ %% Whether to redirect error_logger messages into lager - defaults to true
+ {error_logger_redirect, true}
+ ]},
+
+ %% riak_sysmon config
+ {riak_sysmon, [
+ %% To disable forwarding events of a particular type, use a
+ %% limit of 0.
+ {process_limit, 30},
+ {port_limit, 2},
+
+ %% Finding reasonable limits for a given workload is a matter
+ %% of experimentation.
+ {gc_ms_limit, 100},
+ {heap_word_limit, 40111000},
+
+ %% Configure the following items to 'false' to disable logging
+ %% of that event type.
+ {busy_port, true},
+ {busy_dist_port, true}
+ ]},
+
+ %% SASL config
+ {sasl, [
+ {sasl_error_logger, false}
+ ]}
+
+].
7 include/hello_world_vnode_dispatcher.hrl
@@ -0,0 +1,7 @@
+-ifndef(MISULTIN_RIAK_CORE_VNODE_DISPATCHER).
+-define(MISULTIN_RIAK_CORE_VNODE_DISPATCHER, ok).
+
+-define(VNODE_MASTER(Name, VNode), {Name, {riak_core_vnode_master, start_link, [VNode]}, permanent, 5000, worker, [riak_core_vnode_master]}).
+-define(GEN_SERVER(Name, Worker), {Name, {Worker, start_link, []}, permanent, 5000, worker, [Worker]}).
+
+-endif.
2  node1.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+erl +K true +A 5 -pa ebin -pa deps/*/ebin -config hello_world1 -s hello_world -sname helloworld1@localhost
27 priv/sockjs-0.2.min.js
@@ -0,0 +1,27 @@
+/* SockJS client, version 0.2.1, http://sockjs.org, MIT License
+
+Copyright (C) 2011 VMware, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+// JSON2 by Douglas Crockford (minified).
+var JSON;JSON||(JSON={}),function(){function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c<f;c+=1)h[c]=str(c,i)||"null";e=h.length===0?"[]":gap?"[\n"+gap+h.join(",\n"+gap)+"\n"+g+"]":"["+h.join(",")+"]",gap=g;return e}if(rep&&typeof rep=="object"){f=rep.length;for(c=0;c<f;c+=1)typeof rep[c]=="string"&&(d=rep[c],e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e))}else for(d in i)Object.prototype.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e));e=h.length===0?"{}":gap?"{\n"+gap+h.join(",\n"+gap)+"\n"+g+"}":"{"+h.join(",")+"}",gap=g;return e}}function quote(a){escapable.lastIndex=0;return escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return typeof b=="string"?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function f(a){return a<10?"0"+a:a}"use strict",typeof Date.prototype.toJSON!="function"&&(Date.prototype.toJSON=function(a){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(a){return this.valueOf()});var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;typeof JSON.stringify!="function"&&(JSON.stringify=function(a,b,c){var d;gap="",indent="";if(typeof c=="number")for(d=0;d<c;d+=1)indent+=" ";else typeof c=="string"&&(indent=c);rep=b;if(!b||typeof b=="function"||typeof b=="object"&&typeof b.length=="number")return str("",{"":a});throw new Error("JSON.stringify")}),typeof JSON.parse!="function"&&(JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&typeof e=="object")for(c in e)Object.prototype.hasOwnProperty.call(e,c)&&(d=walk(e,c),d!==undefined?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver=="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")})}()
+
+SockJS=function(){var a=document,b=window,c={},d=function(){};d.prototype.addEventListener=function(a,b){this._listeners||(this._listeners={}),a in this._listeners||(this._listeners[a]=[]);var d=this._listeners[a];c.arrIndexOf(d,b)===-1&&d.push(b);return},d.prototype.removeEventListener=function(a,b){if(!(this._listeners&&a in this._listeners))return;var d=this._listeners[a],e=c.arrIndexOf(d,b);if(e!==-1){d.length>1?this._listeners[a]=d.slice(0,e).concat(d.slice(e+1)):delete this._listeners[a];return}return},d.prototype.dispatchEvent=function(a){var b=a.type,c=Array.prototype.slice.call(arguments,0);this["on"+b]&&this["on"+b].apply(this,c);if(this._listeners&&b in this._listeners)for(var d=0;d<this._listeners[b].length;d++)this._listeners[b][d].apply(this,c)};var e=function(a,b){this.type=a;if(typeof b!="undefined")for(var c in b){if(!b.hasOwnProperty(c))continue;this[c]=b[c]}};e.prototype.toString=function(){var a=[];for(var b in this){if(!this.hasOwnProperty(b))continue;var c=this[b];typeof c=="function"&&(c="[function]"),a.push(b+"="+c)}return"SimpleEvent("+a.join(", ")+")"};var f=function(a){this.events=a||[]};f.prototype.emit=function(a){var b=this,d=Array.prototype.slice.call(arguments,1);!b.nuked&&b["on"+a]&&b["on"+a].apply(b,d),c.arrIndexOf(b.events,a)===-1&&c.log("Event "+JSON.stringify(a)+" not listed "+JSON.stringify(b.events)+" in "+b)},f.prototype.nuke=function(a){var b=this;b.nuked=!0;for(var c=0;c<b.events.length;c++)delete b[b.events[c]]};var g="abcdefghijklmnopqrstuvwxyz0123456789_";c.random_string=function(a,b){b=b||g.length;var c,d=[];for(c=0;c<a;c++)d.push(g.substr(Math.floor(Math.random()*b),1));return d.join("")},c.random_number=function(a){return Math.floor(Math.random()*a)},c.random_number_string=function(a){var b=(""+(a-1)).length,d=Array(b+1).join("0");return(d+c.random_number(a)).slice(-b)},c.getOrigin=function(a){a+="/";var b=a.split("/").slice(0,3);return b.join("/")},c.isSameOriginUrl=function(a){var c=b.location.href.split("/").slice(0,3).join("/");return a.slice(0,c.length)===c},c.getParentDomain=function(a){if(/^[0-9.]*$/.test(a))return a;if(/^\[/.test(a))return a;if(!/[.]/.test(a))return a;var b=a.split(".").slice(1);return b.join(".")},c.objectExtend=function(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a};var h="_jp";c.polluteGlobalNamespace=function(){h in b||(b[h]={})},c.closeFrame=function(a,b){return"c"+JSON.stringify([a,b])},c.userSetCode=function(a){return a===1e3||a>=3e3&&a<=4999},c.countRTO=function(a){var b;return a>100?b=3*a:b=a+200,b},c.log=function(){b.console&&console.log&&console.log.apply&&console.log.apply(console,arguments)},c.bind=function(a,b){return a.bind?a.bind(b):function(){return a.apply(b,arguments)}},c.amendUrl=function(b){var c=a.location;if(!b)throw new Error("Wrong url for SockJS");return b.indexOf("//")===0&&(b=c.protocol+b),b.indexOf("/")===0&&(b=c.protocol+"//"+c.host+b),b=b.replace(/[/]+$/,""),b},c.arrIndexOf=function(a,b){for(var c=0;c<a.length;c++)if(a[c]===b)return c;return-1},c.arrSkip=function(a,b){var d=c.arrIndexOf(a,b);if(d===-1)return a.slice();var e=a.slice(0,d);return e.concat(a.slice(d+1))},c.isArray=Array.isArray||function(a){return{}.toString.call(a).indexOf("Array")>=0},c.delay=function(a,b){return typeof a=="function"&&(b=a,a=0),setTimeout(b,a)};var i=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,j={"\0":"\\u0000","\x01":"\\u0001","\x02":"\\u0002","\x03":"\\u0003","\x04":"\\u0004","\x05":"\\u0005","\x06":"\\u0006","\x07":"\\u0007","\b":"\\b","\t":"\\t","\n":"\\n","\x0b":"\\u000b","\f":"\\f","\r":"\\r","\x0e":"\\u000e","\x0f":"\\u000f","\x10":"\\u0010","\x11":"\\u0011","\x12":"\\u0012","\x13":"\\u0013","\x14":"\\u0014","\x15":"\\u0015","\x16":"\\u0016","\x17":"\\u0017","\x18":"\\u0018","\x19":"\\u0019","\x1a":"\\u001a","\x1b":"\\u001b","\x1c":"\\u001c","\x1d":"\\u001d","\x1e":"\\u001e","\x1f":"\\u001f",'"':'\\"',"\\":"\\\\","\x7f":"\\u007f","\x80":"\\u0080","\x81":"\\u0081","\x82":"\\u0082","\x83":"\\u0083","\x84":"\\u0084","\x85":"\\u0085","\x86":"\\u0086","\x87":"\\u0087","\x88":"\\u0088","\x89":"\\u0089","\x8a":"\\u008a","\x8b":"\\u008b","\x8c":"\\u008c","\x8d":"\\u008d","\x8e":"\\u008e","\x8f":"\\u008f","\x90":"\\u0090","\x91":"\\u0091","\x92":"\\u0092","\x93":"\\u0093","\x94":"\\u0094","\x95":"\\u0095","\x96":"\\u0096","\x97":"\\u0097","\x98":"\\u0098","\x99":"\\u0099","\x9a":"\\u009a","\x9b":"\\u009b","\x9c":"\\u009c","\x9d":"\\u009d","\x9e":"\\u009e","\x9f":"\\u009f","\xad":"\\u00ad","\u0600":"\\u0600","\u0601":"\\u0601","\u0602":"\\u0602","\u0603":"\\u0603","\u0604":"\\u0604","\u070f":"\\u070f","\u17b4":"\\u17b4","\u17b5":"\\u17b5","\u200c":"\\u200c","\u200d":"\\u200d","\u200e":"\\u200e","\u200f":"\\u200f","\u2028":"\\u2028","\u2029":"\\u2029","\u202a":"\\u202a","\u202b":"\\u202b","\u202c":"\\u202c","\u202d":"\\u202d","\u202e":"\\u202e","\u202f":"\\u202f","\u2060":"\\u2060","\u2061":"\\u2061","\u2062":"\\u2062","\u2063":"\\u2063","\u2064":"\\u2064","\u2065":"\\u2065","\u2066":"\\u2066","\u2067":"\\u2067","\u2068":"\\u2068","\u2069":"\\u2069","\u206a":"\\u206a","\u206b":"\\u206b","\u206c":"\\u206c","\u206d":"\\u206d","\u206e":"\\u206e","\u206f":"\\u206f","\ufeff":"\\ufeff","\ufff0":"\\ufff0","\ufff1":"\\ufff1","\ufff2":"\\ufff2","\ufff3":"\\ufff3","\ufff4":"\\ufff4","\ufff5":"\\ufff5","\ufff6":"\\ufff6","\ufff7":"\\ufff7","\ufff8":"\\ufff8","\ufff9":"\\ufff9","\ufffa":"\\ufffa","\ufffb":"\\ufffb","\ufffc":"\\ufffc","\ufffd":"\\ufffd","\ufffe":"\\ufffe","\uffff":"\\uffff"},k=/[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g,l,m=JSON&&JSON.stringify||function(a){return i.lastIndex=0,i.test(a)&&(a=a.replace(i,function(a){return j[a]})),'"'+a+'"'},n=function(a){var b,c={},d=[];for(b=0;b<65536;b++)d.push(String.fromCharCode(b));return a.lastIndex=0,d.join("").replace(a,function(a){return c[a]="\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4),""}),a.lastIndex=0,c};c.quote=function(a){var b=m(a);return k.lastIndex=0,k.test(b)?(l||(l=n(k)),b.replace(k,function(a){return l[a]})):b};var o=["websocket","xdr-streaming","xhr-streaming","iframe-eventsource","iframe-htmlfile","xdr-polling","xhr-polling","iframe-xhr-polling","jsonp-polling"];c.probeProtocols=function(){var a={};for(var b=0;b<o.length;b++){var c=o[b];a[c]=t[c]&&t[c].enabled()}return a},c.detectProtocols=function(a,b,c){var d={},e=[];b||(b=o);for(var f=0;f<b.length;f++){var g=b[f];d[g]=a[g]}var h=function(a){var b=a.shift();d[b]?e.push(b):a.length>0&&h(a)};return c.websocket!==!1&&h(["websocket"]),d["xdr-streaming"]&&!c.cookie_needed?e.push("xdr-streaming"):h(["xhr-streaming","iframe-eventsource","iframe-htmlfile"]),d["xdr-polling"]&&!c.cookie_needed?e.push("xdr-polling"):h(["xhr-polling","iframe-xhr-polling","jsonp-polling"]),e};var p="_sockjs_global";c.createHook=function(){var a="a"+c.random_string(8);if(!(p in b)){var d={};b[p]=function(a){return a in d||(d[a]={id:a,del:function(){delete d[a]}}),d[a]}}return b[p](a)},c.attachMessage=function(a){c.attachEvent("message",a)},c.attachEvent=function(c,d){typeof b.addEventListener!="undefined"?b.addEventListener(c,d,!1):(a.attachEvent("on"+c,d),b.attachEvent("on"+c,d))},c.detachMessage=function(a){c.detachEvent("message",a)},c.detachEvent=function(c,d){typeof b.addEventListener!="undefined"?b.removeEventListener(c,d,!1):(a.detachEvent("on"+c,d),b.detachEvent("on"+c,d))};var q={};c.unload_add=function(a){var b=c.random_string(8);return q[b]=a,b},c.unload_del=function(a){a in q&&delete q[a]},c.attachEvent("unload",function(){for(var a in q)q[a]()}),c.createIframe=function(b,d){var e=a.createElement("iframe"),f,g=function(){clearTimeout(f);try{e.onload=null}catch(a){}e.onerror=null},h=function(){e&&(g(),e.src="about:blank",setTimeout(function(){e&&e.parentNode.removeChild(e),e=null},0),c.detachEvent("unload",h))},i=function(a){e&&(h(),d(a))};return e.src=b,e.style.display="none",e.style.position="absolute",e.onerror=function(){i("onerror")},e.onload=function(){clearTimeout(f),f=setTimeout(function(){i("onload timeout")},2e3)},a.body.appendChild(e),f=setTimeout(function(){i("timeout")},5e3),c.attachEvent("unload",h),{iframe:e,cleanup:h,loaded:g}},c.createHtmlfile=function(a,d){var e=new ActiveXObject("htmlfile"),f,g,i=function(){clearTimeout(f)},j=function(){if(e){i(),c.detachEvent("unload",j);try{g.src="about:blank"}catch(a){}g.parentNode.removeChild(g),g=e=null,CollectGarbage()}},k=function(a){e&&(j(),d(a))};e.open(),e.write('<html><script>document.domain="'+document.domain+'";'+"</s"+"cript></html>"),e.close(),e.parentWindow[h]=b[h];var l=e.createElement("div");return e.body.appendChild(l),g=e.createElement("iframe"),l.appendChild(g),g.src=a,f=setTimeout(function(){k("timeout")},5e3),c.attachEvent("unload",j),{iframe:g,cleanup:j,loaded:i}};var r=c.XHRObject=function(a,b,d){var e=this;c.delay(function(){e._start(a,b,d)})};r.prototype=new f(["chunk","finish"]),r.prototype._start=function(a,d,e){var f=this;try{f.xhr=new b.ActiveXObject("Microsoft.XMLHTTP"),d+=(d.indexOf("?")===-1?"?":"&")+"t="+ +(new Date)}catch(g){}f.xhr||(f.xhr=new XMLHttpRequest),f.unload_ref=c.unload_add(function(){f._cleanup(!0)});try{f.xhr.open(a,d,!0)}catch(h){f.emit("finish",0,""),f._cleanup();return}"withCredentials"in f.xhr&&(f.xhr.withCredentials="true"),f.xhr.onreadystatechange=function(){if(f.xhr){var a=f.xhr;switch(a.readyState){case 3:try{var b=a.status,c=a.responseText;f.emit("chunk",b,c)}catch(a){}break;case 4:f.emit("finish",a.status,a.responseText),f._cleanup(!1)}}},f.xhr.send(e)},r.prototype._cleanup=function(a){var b=this;if(!b.xhr)return;c.unload_del(b.unload_ref),b.xhr.onreadystatechange=function(){};if(a)try{b.xhr.abort()}catch(d){}b.unload_ref=b.xhr=null},r.prototype.close=function(){var a=this;a.nuke(),a._cleanup(!0)};var s=c.XDRObject=function(a,b,d){var e=this;c.delay(function(){e._start(a,b,d)})};s.prototype=new f(["chunk","finish"]),s.prototype._start=function(a,b,d){var e=this,f=new XDomainRequest;b+=(b.indexOf("?")===-1?"?":"&")+"t="+ +(new Date);var g=f.ontimeout=f.onerror=function(){e.emit("finish",0,""),e._cleanup(!1)};f.onprogress=function(){e.emit("chunk",200,f.responseText)},f.onload=function(){e.emit("finish",200,f.responseText),e._cleanup(!1)},e.xdr=f,e.unload_ref=c.unload_add(function(){e._cleanup(!0)});try{e.xdr.open(a,b),e.xdr.send(d)}catch(h){g()}},s.prototype._cleanup=function(a){var b=this;if(!b.xdr)return;c.unload_del(b.unload_ref),b.xdr.ontimeout=b.xdr.onerror=b.xdr.onprogress=b.xdr.onload=null;if(a)try{b.xdr.abort()}catch(d){}b.unload_ref=b.xdr=null},s.prototype.close=function(){var a=this;a.nuke(),a._cleanup(!0)},c.isXHRCorsCapable=function(){return b.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest?1:b.XDomainRequest?2:G.enabled()?3:4};var t=function(a,b,d){var e=this,f;e._options={devel:!1,debug:!1,protocols_whitelist:[],info:undefined,rtt:undefined},d&&c.objectExtend(e._options,d),e._base_url=c.amendUrl(a),e._server=e._options.server||c.random_number_string(1e3),e._options.protocols_whitelist&&e._options.protocols_whitelist.length?f=e._options.protocols_whitelist:(typeof b=="string"&&b.length>0?f=[b]:c.isArray(b)?f=b:f=null,f&&e._debug('Deprecated API: Use "protocols_whitelist" option instead of supplying protocol list as a second parameter to SockJS constructor.')),e._protocols=[],e.protocol=null,e.readyState=t.CONNECTING;var g=N(e._base_url);g.onfinish=function(a,b){a?(e._options.info&&(a=c.objectExtend(a,e._options.info)),e._options.rtt&&(b=e._options.rtt),e._applyInfo(a,b,f),e._didClose()):e._didClose(1002,"Can't connect to server",!0)}};t.prototype=new d,t.version="0.2.1",t.CONNECTING=0,t.OPEN=1,t.CLOSING=2,t.CLOSED=3,t.prototype._debug=function(){this._options.debug&&c.log.apply(c,arguments)},t.prototype._dispatchOpen=function(){var a=this;a.readyState===t.CONNECTING?(a._transport_tref&&(clearTimeout(a._transport_tref),a._transport_tref=null),a.readyState=t.OPEN,a.dispatchEvent(new e("open"))):a._didClose(1006,"Server lost session")},t.prototype._dispatchMessage=function(a){var b=this;if(b.readyState!==t.OPEN)return;b.dispatchEvent(new e("message",{data:a}))},t.prototype._dispatchHeartbeat=function(a){var b=this;if(b.readyState!==t.OPEN)return;b.dispatchEvent(new e("heartbeat",{}))},t.prototype._didClose=function(a,b,d){var f=this;if(f.readyState!==t.CONNECTING&&f.readyState!==t.OPEN&&f.readyState!==t.CLOSING)throw new Error("INVALID_STATE_ERR");f._transport&&f._transport.doCleanup(),f._transport=null;var g=new e("close",{code:a,reason:b,wasClean:c.userSetCode(a)});if(!c.userSetCode(a)&&f.readyState===t.CONNECTING&&!d){if(f._try_next_protocol(g))return;g=new e("close",{code:2e3,reason:"All transports failed",wasClean:!1,last_event:g})}f.readyState=t.CLOSED,c.delay(function(){f.dispatchEvent(g)})},t.prototype._didMessage=function(a){var b=this,c=a.slice(0,1);switch(c){case"o":b._dispatchOpen();break;case"a":var d=JSON.parse(a.slice(1)||"[]");for(var e=0;e<d.length;e++)b._dispatchMessage(d[e]);break;case"m":var d=JSON.parse(a.slice(1)||"null");b._dispatchMessage(d);break;case"c":var d=JSON.parse(a.slice(1)||"[]");b._didClose(d[0],d[1]);break;case"h":b._dispatchHeartbeat()}},t.prototype._try_next_protocol=function(b){var d=this;d.protocol&&(d._debug("Closed transport:",d.protocol,""+b),d.protocol=null),d._transport_tref&&(clearTimeout(d._transport_tref),d._transport_tref=null);for(;;){var e=d.protocol=d._protocols.shift();if(!e)return!1;if(t[e]&&t[e].need_body===!0&&!a.body)return d._protocols.unshift(e),d.protocol="waiting-for-load",c.attachEvent("load",function(){d._try_next_protocol()}),!0;if(!!t[e]&&!!t[e].enabled(d._options)){var f=t[e].roundTrips||1,g=(d._options.rto||0)*f||5e3;d._transport_tref=c.delay(g,function(){d.readyState===t.CONNECTING&&d._didClose(2007,"Transport timeouted")});var h=c.random_string(8),i=d._base_url+"/"+d._server+"/"+h;return d._debug("Opening transport:",e," url:"+i," RTO:"+d._options.rto),d._transport=new t[e](d,i,d._base_url),!0}d._debug("Skipping transport:",e)}},t.prototype.close=function(a,b){var d=this;if(a&&!c.userSetCode(a))throw new Error("INVALID_ACCESS_ERR");return d.readyState!==t.CONNECTING&&d.readyState!==t.OPEN?!1:(d.readyState=t.CLOSING,d._didClose(a||1e3,b||"Normal closure"),!0)},t.prototype.send=function(a){var b=this;if(b.readyState===t.CONNECTING)throw new Error("INVALID_STATE_ERR");return b.readyState===t.OPEN&&b._transport.doSend(c.quote(""+a)),!0},t.prototype._applyInfo=function(a,b,d){var e=this;e._options.info=a,e._options.rtt=b,e._options.rto=c.countRTO(b);var f=c.probeProtocols();e._protocols=c.detectProtocols(f,d,a)};var u=t.websocket=function(a,d){var e=this,f=d+"/websocket";f.slice(0,5)==="https"?f="wss"+f.slice(5):f="ws"+f.slice(4),e.ri=a,e.url=f;var g=b.WebSocket||b.MozWebSocket;e.ws=new g(e.url),e.ws.onmessage=function(a){e.ri._didMessage(a.data)},e.unload_ref=c.unload_add(function(){e.ws.close()}),e.ws.onclose=function(){e.ri._didMessage(c.closeFrame(1006,"WebSocket connection broken"))}};u.prototype.doSend=function(a){this.ws.send(a)},u.prototype.doCleanup=function(){var a=this,b=a.ws;b&&(b.onmessage=b.onclose=null,b.close(),c.unload_del(a.unload_ref),a.unload_ref=a.ri=a.ws=null)},u.enabled=function(){return!!b.WebSocket||!!b.MozWebSocket};var v=function(){};v.prototype.send_constructor=function(a){var b=this;b.send_buffer=[],b.sender=a},v.prototype.doSend=function(a){var b=this;b.send_buffer.push(a),b.send_stop||b.send_schedule()},v.prototype.send_schedule_wait=function(){var a=this,b;a.send_stop=function(){a.send_stop=null,clearTimeout(b)},b=c.delay(25,function(){a.send_stop=null,a.send_schedule()})},v.prototype.send_schedule=function(){var a=this;if(a.send_buffer.length>0){var b="["+a.send_buffer.join(",")+"]";a.send_stop=a.sender(a.trans_url,b,function(){a.send_stop=null,a.send_schedule_wait()}),a.send_buffer=[]}},v.prototype.send_destructor=function(){var a=this;a._send_stop&&a._send_stop(),a._send_stop=null};var w=function(b,d,e){var f=this;if(!("_send_form"in f)){var g=f._send_form=a.createElement("form"),h=f._send_area=a.createElement("textarea");h.name="d",g.style.display="none",g.style.position="absolute",g.method="POST",g.enctype="application/x-www-form-urlencoded",g.acceptCharset="UTF-8",g.appendChild(h),a.body.appendChild(g)}var g=f._send_form,h=f._send_area,i="a"+c.random_string(8);g.target=i,g.action=b+"/jsonp_send?i="+i;var j;try{j=a.createElement('<iframe name="'+i+'">')}catch(k){j=a.createElement("iframe"),j.name=i}j.id=i,g.appendChild(j),j.style.display="none";try{h.value=d}catch(l){alert("Your browser is seriously broken. Go home! "+l.message)}g.submit();var m=function(a){if(!j.onerror)return;j.onreadystatechange=j.onerror=j.onload=null,c.delay(500,function(){j.parentNode.removeChild(j),j=null}),h.value=null,e()};return j.onerror=j.onload=m,j.onreadystatechange=function(a){j.readyState=="complete"&&m()},m},x=function(a){return function(b,c,d){var e=new a("POST",b+"/xhr_send",c);return e.onfinish=function(a,b){d(a)},function(a){d(0,a)}}},y=function(b,d){var e,f=a.createElement("script"),g,h=function(a){g&&(g.parentNode.removeChild(g),g=null),f&&(clearTimeout(e),f.parentNode.removeChild(f),f.onreadystatechange=f.onerror=f.onload=f.onclick=null,f=null,d(a),d=null)},i=!1,j=null;f.id="a"+c.random_string(8),f.src=b,f.type="text/javascript",f.charset="UTF-8",f.onerror=function(a){j||(j=setTimeout(function(){i||h(c.closeFrame(1006,"JSONP script loaded abnormally (onerror)"))},1e3))},f.onload=function(a){h(c.closeFrame(1006,"JSONP script loaded abnormally (onload)"))},f.onreadystatechange=function(a){if(/loaded|closed/.test(f.readyState)){if(f&&f.htmlFor&&f.onclick){i=!0;try{f.onclick()}catch(b){}}f&&h(c.closeFrame(1006,"JSONP script loaded abnormally (onreadystatechange)"))}};if(typeof f.async=="undefined"&&a.attachEvent)if(!/opera/i.test(navigator.userAgent)){try{f.htmlFor=f.id,f.event="onclick"}catch(k){}f.async=!0}else g=a.createElement("script"),g.text="try{var a = document.getElementById('"+f.id+"'); if(a)a.onerror();}catch(x){};",f.async=g.async=!1;typeof f.async!="undefined"&&(f.async=!0),e=setTimeout(function(){h(c.closeFrame(1006,"JSONP script loaded abnormally (timeout)"))},35e3);var l=a.getElementsByTagName("head")[0];return l.insertBefore(f,l.firstChild),g&&l.insertBefore(g,l.firstChild),h},z=t["jsonp-polling"]=function(a,b){c.polluteGlobalNamespace();var d=this;d.ri=a,d.trans_url=b,d.send_constructor(w),d._schedule_recv()};z.prototype=new v,z.prototype._schedule_recv=function(){var a=this,b=function(b){a._recv_stop=null,b&&(a._is_closing||a.ri._didMessage(b)),a._is_closing||a._schedule_recv()};a._recv_stop=A(a.trans_url+"/jsonp",y,b)},z.enabled=function(){return!0},z.need_body=!0,z.prototype.doCleanup=function(){var a=this;a._is_closing=!0,a._recv_stop&&a._recv_stop(),a.ri=a._recv_stop=null,a.send_destructor()};var A=function(a,d,e){var f="a"+c.random_string(6),g=a+"?c="+escape(h+"."+f),i=function(a){delete b[h][f],e(a)},j=d(g,i);b[h][f]=j;var k=function(){b[h][f]&&b[h][f](c.closeFrame(1e3,"JSONP user aborted read"))};return k},B=function(){};B.prototype=new v,B.prototype.run=function(a,b,c,d,e){var f=this;f.ri=a,f.trans_url=b,f.send_constructor(x(e)),f.poll=new V(a,d,b+c,e)},B.prototype.doCleanup=function(){var a=this;a.poll&&(a.poll.abort(),a.poll=null)};var C=t["xhr-streaming"]=function(a,b){this.run(a,b,"/xhr_streaming",$,c.XHRObject)};C.prototype=new B,C.enabled=function(){return b.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest},C.roundTrips=2;var D=t["xdr-streaming"]=function(a,b){this.run(a,b,"/xhr_streaming",$,c.XDRObject)};D.prototype=new B,D.enabled=function(){return!!b.XDomainRequest},D.roundTrips=2;var E=t["xhr-polling"]=function(a,b){this.run(a,b,"/xhr",$,c.XHRObject)};E.prototype=new B,E.enabled=C.enabled,E.roundTrips=2;var F=t["xdr-polling"]=function(a,b){this.run(a,b,"/xhr",$,c.XDRObject)};F.prototype=new B,F.enabled=D.enabled,F.roundTrips=2;var G=function(){};G.prototype.i_constructor=function(a,b,d){var e=this;e.ri=a,e.origin=c.getOrigin(d),e.base_url=d,e.trans_url=b;var f=d+"/iframe.html";e.ri._options.devel&&(f+="?t="+ +(new Date)),e.window_id=c.random_string(8),f+="#"+e.window_id,e.iframeObj=c.createIframe(f,function(a){e.ri._didClose(1006,"Unable to load an iframe ("+a+")")}),e.onmessage_cb=c.bind(e.onmessage,e),c.attachMessage(e.onmessage_cb)},G.prototype.doCleanup=function(){var a=this;if(a.iframeObj){c.detachMessage(a.onmessage_cb);try{a.iframeObj.iframe.contentWindow&&a.postMessage("c")}catch(b){}a.iframeObj.cleanup(),a.iframeObj=null,a.onmessage_cb=a.iframeObj=null}},G.prototype.onmessage=function(a){var b=this;if(a.origin!==b.origin)return;var c=a.data.slice(0,8),d=a.data.slice(8,9),e=a.data.slice(9);if(c!==b.window_id)return;switch(d){case"s":b.iframeObj.loaded(),b.postMessage("s",JSON.stringify([t.version,b.protocol,b.trans_url,b.base_url]));break;case"t":b.ri._didMessage(e)}},G.prototype.postMessage=function(a,b){var c=this;c.iframeObj.iframe.contentWindow.postMessage(c.window_id+a+(b||""),c.origin)},G.prototype.doSend=function(a){this.postMessage("m",a)},G.enabled=function(){var a=navigator&&navigator.userAgent&&navigator.userAgent.indexOf("Konqueror")!==-1;return(typeof b.postMessage=="function"||typeof b.postMessage=="object")&&!a};var H,I=function(a,d){parent!==b?parent.postMessage(H+a+(d||""),"*"):c.log("Can't postMessage, no parent window.",a,d)},J=function(){};J.prototype._didClose=function(a,b){I("t",c.closeFrame(a,b))},J.prototype._didMessage=function(a){I("t",a)},J.prototype._doSend=function(a){this._transport.doSend(a)},J.prototype._doCleanup=function(){this._transport.doCleanup()},t.bootstrap_iframe=function(){var d;H=a.location.hash.slice(1);var e=function(a){if(a.source!==parent)return;var e=a.data.slice(0,8),f=a.data.slice(8,9),g=a.data.slice(9);if(e!==H)return;switch(f){case"s":var h=JSON.parse(g),i=h[0],j=h[1],k=h[2],l=h[3];i!==t.version&&c.log('Incompatibile SockJS! Main site uses: "'+i+'", the iframe:'+' "'+t.version+'".');if(!c.isSameOriginUrl(k)||!c.isSameOriginUrl(l)){c.log("Can't connect to different domain from within an iframe. ("+JSON.stringify([b.location.href,k,l])+")");return}d=new J,d._transport=new J[j](d,k,l);break;case"m":d._doSend(g);break;case"c":d&&d._doCleanup(),d=null}};c.attachMessage(e),I("s")};var K=function(a,b){var d=this;c.delay(function(){d.doXhr(a,b)})};K.prototype=new f(["finish"]),K.prototype.doXhr=function(a,b){var d=this,e=(new Date).getTime(),f=new b("GET",a+"/info",null),g=c.delay(8e3,function(){f.ontimeout()});f.onfinish=function(a,b){clearTimeout(g),g=null;if(a===200){var c=(new Date).getTime()-e,f=JSON.parse(b);typeof f!="object"&&(f={}),d.emit("finish",f,c)}else d.emit("finish")},f.ontimeout=function(){f.close(),d.emit("finish")}};var L=function(b){var d=this,e=function(){var a=new G;a.protocol="w-iframe-info-receiver";var c=function(b){if(typeof b=="string"&&b.substr(0,1)==="m"){var c=JSON.parse(b.substr(1)),e=c[0],f=c[1];d.emit("finish",e,f)}else d.emit("finish");a.doCleanup(),a=null},e={_options:{},_didClose:c,_didMessage:c};a.i_constructor(e,b,b)};a.body?e():c.attachEvent("load",e)};L.prototype=new f(["finish"]);var M=function(){var a=this;c.delay(function(){a.emit("finish",{},2e3)})};M.prototype=new f(["finish"]);var N=function(a){if(c.isSameOriginUrl(a))return new K(a,c.XHRObject);switch(c.isXHRCorsCapable()){case 1:return new K(a,c.XHRObject);case 2:return new K(a,c.XDRObject);case 3:return new L(a);default:return new M}},O=J["w-iframe-info-receiver"]=function(a,b,d){var e=new K(d,c.XHRObject);e.onfinish=function(b,c){a._didMessage("m"+JSON.stringify([b,c])),a._didClose()}};O.prototype.doCleanup=function(){};var P=t["iframe-eventsource"]=function(){var a=this;a.protocol="w-iframe-eventsource",a.i_constructor.apply(a,arguments)};P.prototype=new G,P.enabled=function(){return"EventSource"in b&&G.enabled()},P.need_body=!0,P.roundTrips=3;var Q=J["w-iframe-eventsource"]=function(a,b){this.run(a,b,"/eventsource",W,c.XHRObject)};Q.prototype=new B;var R=t["iframe-xhr-polling"]=function(){var a=this;a.protocol="w-iframe-xhr-polling",a.i_constructor.apply(a,arguments)};R.prototype=new G,R.enabled=function(){return b.XMLHttpRequest&&G.enabled()},R.need_body=!0,R.roundTrips=3;var S=J["w-iframe-xhr-polling"]=function(a,b){this.run(a,b,"/xhr",$,c.XHRObject)};S.prototype=new B;var T=t["iframe-htmlfile"]=function(){var a=this;a.protocol="w-iframe-htmlfile",a.i_constructor.apply(a,arguments)};T.prototype=new G,T.enabled=function(){return G.enabled()},T.need_body=!0,T.roundTrips=3;var U=J["w-iframe-htmlfile"]=function(a,b){this.run(a,b,"/htmlfile",Z,c.XHRObject)};U.prototype=new B;var V=function(a,b,c,d){var e=this;e.ri=a,e.Receiver=b,e.recv_url=c,e.AjaxObject=d,e._scheduleRecv()};V.prototype._scheduleRecv=function(){var a=this,b=a.poll=new a.Receiver(a.recv_url,a.AjaxObject),c=0;b.onmessage=function(b){c+=1,a.ri._didMessage(b.data)},b.onclose=function(c){a.poll=b=b.onmessage=b.onclose=null,a.poll_is_closing||(c.reason==="permanent"?a.ri._didClose(1006,"Polling error ("+c.reason+")"):a._scheduleRecv())}},V.prototype.abort=function(){var a=this;a.poll_is_closing=!0,a.poll&&a.poll.abort()};var W=function(a){var b=this,d=new EventSource(a);d.onmessage=function(a){b.dispatchEvent(new e("message",{data:unescape(a.data)}))},b.es_close=d.onerror=function(a,f){var g=f?"user":d.readyState!==2?"network":"permanent";b.es_close=d.onmessage=d.onerror=null,d.close(),d=null,c.delay(200,function(){b.dispatchEvent(new e("close",{reason:g}))})}};W.prototype=new d,W.prototype.abort=function(){var a=this;a.es_close&&a.es_close({},!0)};var X,Y=function(){if(X===undefined)if("ActiveXObject"in b)try{X=!!(new ActiveXObject("htmlfile"))}catch(a){}else X=!1;return X},Z=function(a){var d=this;c.polluteGlobalNamespace(),d.id="a"+c.random_string(6,26),a+=(a.indexOf("?")===-1?"?":"&")+"c="+escape(h+"."+d.id);var f=Y()?c.createHtmlfile:c.createIframe,g;b[h][d.id]={start:function(){g.loaded()},message:function(a){d.dispatchEvent(new e("message",{data:a}))},stop:function(){d.iframe_close({},"network")}},d.iframe_close=function(a,c){g.cleanup(),d.iframe_close=g=null,delete b[h][d.id],d.dispatchEvent(new e("close",{reason:c}))},g=f(a,function(a){d.iframe_close({},"permanent")})};Z.prototype=new d,Z.prototype.abort=function(){var a=this;a.iframe_close&&a.iframe_close({},"user")};var $=function(a,b){var c=this,d=0;c.xo=new b("POST",a,null),c.xo.onchunk=function(a,b){if(a!==200)return;for(;;){var f=b.slice(d),g=f.indexOf("\n");if(g===-1)break;d+=g+1;var h=f.slice(0,g);c.dispatchEvent(new e("message",{data:h}))}},c.xo.onfinish=function(a,b){c.xo.onchunk(a,b),c.xo=null;var d=a===200?"network":"permanent";c.dispatchEvent(new e("close",{reason:d}))}};return $.prototype=new d,$.prototype.abort=function(){var a=this;a.xo&&(a.xo.close(),a.dispatchEvent(new e("close",{reason:"user"})),a.xo=null)},t.getUtils=function(){return c},t.getIframeTransport=function(){return G},t}(),"_sockjs_onload"in window&&setTimeout(_sockjs_onload,1)
22 priv/ws.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<html>
+ <head>
+ <title>riak_core / cowboy Integeration Test</title>
+ <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
+ <script src="http://cdn.sockjs.org/sockjs-0.2.min.js"></script>
+ <script>
+ var ws = new SockJS("/data");
+ ws.onmessage = function(msg) {
+ console.log("from server: ", msg.data);
+ $("#content").html(msg.data);
+ }
+ ws.onopen = function() {
+ console.log("sending data to client...");
+ ws.send("data from client");
+ }
+ </script>
+ </head>
+ <body>
+ <div id="content"></div>
+ </body>
+</html>
BIN  rebar
Binary file not shown
12 rebar.config
@@ -0,0 +1,12 @@
+{erl_opts, [
+ debug_info,
+ {parse_transform, lager_transform}
+ %fail_on_warning
+]}.
+
+{deps, [
+ {cowboy, ".*", {git, "https://github.com/extend/cowboy.git", "HEAD"}},
+ {mimetypes, ".*", {git, "https://github.com/spawngrid/mimetypes.git", "HEAD"}},
+ {sockjs, ".*", {git, "https://github.com/sockjs/sockjs-erlang.git", "HEAD"}},
+ {riak_core, ".*", {git, "https://github.com/basho/riak_core.git", {tag, "1.1.1"}}}
+]}.
13 src/hello_world.app.src
@@ -0,0 +1,13 @@
+{application, hello_world, [
+ {description, "Hello World! Test App"},
+ {vsn, "1.0"},
+ {registered, []},
+ {applications, [
+ kernel,
+ stdlib,
+ cowboy,
+ riak_core
+ ]},
+ {mod, { hello_world_app, []}},
+ {env, []}
+]}.
21 src/hello_world.erl
@@ -0,0 +1,21 @@
+-module(hello_world).
+
+-export([
+ start/0,
+ stop/0
+]).
+
+start() ->
+ application:start(crypto),
+ application:start(sasl),
+ application:start(lager),
+ application:start(webmachine),
+ application:start(os_mon),
+ application:start(riak_sysmon),
+ application:start(riak_core),
+ application:start(sockjs),
+ application:start(cowboy),
+ application:start(hello_world).
+
+stop() ->
+ ok.
20 src/hello_world_app.erl
@@ -0,0 +1,20 @@
+-module(hello_world_app).
+-behaviour(application).
+
+-export([
+ start/2,
+ stop/1
+]).
+
+start(_StartType, _StartArgs) ->
+ case hello_world_sup:start_link() of
+ {ok, Pid} ->
+ ok = riak_core:register([{vnode_module, hello_world_vnode}]),
+ ok = riak_core_node_watcher:service_up(hello_world, self()),
+
+ {ok, Pid};
+ Else -> Else
+ end.
+
+stop(_State) ->
+ ok.
20 src/hello_world_sup.erl
@@ -0,0 +1,20 @@
+-module(hello_world_sup).
+-behaviour(supervisor).
+
+-include("hello_world_vnode_dispatcher.hrl").
+
+-export([
+ start_link/0,
+ init/1
+]).
+
+start_link() ->
+ supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+
+init(_Args) ->
+ Workers = [
+ ?GEN_SERVER(hello_world_vnode_dispatcher_master, hello_world_vnode_dispatcher),
+ ?VNODE_MASTER(hello_world_vnode_master, hello_world_vnode)
+ ],
+
+ {ok, {{one_for_one, 10, 10}, Workers}}.
77 src/hello_world_vnode.erl
@@ -0,0 +1,77 @@
+-module(hello_world_vnode).
+-behaviour(riak_core_vnode).
+
+-include_lib("riak_core/include/riak_core_vnode.hrl").
+
+-export([
+ delete/1,
+ encode_handoff_item/2,
+ handle_command/3,
+ handle_coverage/4,
+ handle_exit/3,
+ handle_handoff_command/3,
+ handle_handoff_data/2,
+ handoff_cancelled/1,
+ handoff_finished/2,
+ handoff_starting/2,
+ init/1,
+ is_empty/1,
+ start_vnode/1,
+ terminate/2
+]).
+
+-record(state, {
+ partition :: partition()
+}).
+
+start_vnode(I) ->
+ riak_core_vnode_master:get_vnode_pid(I, ?MODULE).
+
+init([Partition]) ->
+ lager:debug("started ~p at partition ~p", [?MODULE, Partition]),
+ {ok, #state { partition = Partition }}.
+
+handle_command({sockjs, Data, Conn}, _Sender, State) ->
+ lager:info("Got data from client: ~p", [Data]),
+ Conn:send(<<"Hello World!">>),
+ {noreply, State};
+
+handle_command(Msg, _Sender, State) ->
+ lager:warning("unhandled command: ~p~n", [Msg]),
+ {noreply, State}.
+
+handle_coverage(Request, KeySpaces, Sender, State) ->
+ lager:debug("handle_coverage: ~p ~p ~p ~p~n", [Request, KeySpaces, Sender, State]),
+ {continue, State}.
+
+handle_exit(Pid, Reason, State) ->
+ lager:debug("handle exit: ~p ~p~n", [Pid, Reason]),
+ {stop, Reason, State}.
+
+handle_handoff_command(Message, Sender, State) ->
+ lager:debug("handle handoff: ~p ~p~n", [Message, Sender]),
+ {forward, State}.
+
+handoff_starting(_TargetNode, State) ->
+ {true, State}.
+
+handoff_cancelled(State) ->
+ {ok, State}.
+
+handoff_finished(_TargetNode, State) ->
+ {ok, State}.
+
+handle_handoff_data(_Data, State) ->
+ {reply, ok, State}.
+
+encode_handoff_item(_ObjectName, _ObjectValue) ->
+ <<>>.
+
+is_empty(State) ->
+ {true, State}.
+
+delete(State) ->
+ {ok, State}.
+
+terminate(_Reason, _State) ->
+ ok.
94 src/hello_world_vnode_dispatcher.erl
@@ -0,0 +1,94 @@
+-module(hello_world_vnode_dispatcher).
+-behaviour(gen_server2).
+
+-include("hello_world_vnode_dispatcher.hrl").
+
+-export([
+ start_link/0,
+ init/1,
+ handle_call/3,
+ handle_cast/2,
+ handle_info/2,
+ terminate/2,
+ code_change/3
+]).
+
+-record(state, { site, server, config }).
+
+start_link() ->
+ gen_server2:start_link({local, ?MODULE}, ?MODULE, [], [{timeout, infinity}]).
+
+init([]) ->
+ {ok, MasterNode} = application:get_env(master_node),
+
+ case node() of
+ MasterNode -> ok;
+ _ -> riak_core:join(MasterNode)
+ end,
+
+ WebPort = case application:get_env(web_port) of
+ {ok, P} -> P;
+ _ -> 3000
+ end,
+
+ DataState = sockjs_handler:init_state(<<"/data">>, fun sockjs_data_dispatch/2, [{cookie_needed, true}]),
+ Routes = [
+ % All hosts
+ {'_', [
+ % Data handler
+ {[<<"data">>, '...'], sockjs_cowboy_handler, DataState},
+ % Static files
+ {[<<"static">>, '...'], cowboy_http_static, [
+ {directory, {priv_dir, hello_world, []}},
+ {mimetypes, {fun mimetypes:path_to_mimes/2, default}}
+ ]}
+ ]}
+ ],
+
+ lager:info("Starting SockJS server on ~p", [WebPort]),
+ cowboy:start_listener(http, 100, cowboy_tcp_transport, [{port, WebPort}], cowboy_http_protocol, [{dispatch, Routes}]),
+
+ {ok, #state {}}.
+
+handle_call(Msg, From, State) ->
+ io:format("handle_call: ~p ~p ~p~n", [Msg, From, State]),
+ {noreply, State}.
+
+handle_cast(Msg, State) ->
+ io:format("handle_cast: ~p ~p~n", [Msg, State]),
+ {noreply, State}.
+
+handle_info(Msg, State) ->
+ io:format("handle_info: ~p ~p~n", [Msg, State]),
+ {noreply, State}.
+
+terminate(Reason, State) ->
+ cowboy:stop_listener(http),
+ io:format("terminate: ~p ~p~n", [Reason, State]),
+ ok.
+
+code_change(OldVsn, State, Extra) ->
+ io:format("code_change: ~p ~p ~p~n", [OldVsn, State, Extra]),
+ {ok, State}.
+
+sockjs_data_dispatch(Conn, {recv, Data}) ->
+ Id = mkid(websocket, data),
+ Hash = riak_core_util:chash_key({<<"data">>, Id}),
+
+ Index = case riak_core_apl:get_primary_apl(Hash, 1, hello_world) of
+ [{Idx, _Type}] -> Idx;
+ _ -> {0, node()}
+ end,
+ lager:debug("Dispatching to ~p", [Index]),
+
+ riak_core_vnode_master:command(Index, {sockjs, Data, Conn}, hello_world_vnode_master),
+
+ ok;
+sockjs_data_dispatch(_Conn, _) -> ok.
+
+mkid(Method, Resource) ->
+ % Absconded from riak_core_util:mkclientid/1
+ {{Y,Mo,D},{H,Mi,S}} = erlang:universaltime(),
+ {_,_,NowPart} = now(),
+ Id = erlang:phash2([Y,Mo,D,H,Mi,S,Method,Resource,NowPart]),
+ io_lib:format("~p", [Id]).
Please sign in to comment.
Something went wrong with that request. Please try again.