dripdrop 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/README.md +21 -102
- data/Rakefile +4 -2
- data/VERSION +1 -1
- data/doc_img/topology.png +0 -0
- data/dripdrop.gemspec +19 -20
- data/example/agent_test.rb +1 -1
- data/example/pubsub.rb +18 -0
- data/example/pushpull.rb +21 -0
- data/lib/dripdrop/agent.rb +24 -6
- data/lib/dripdrop/handlers/websockets.rb +68 -0
- data/lib/dripdrop/handlers/zeromq.rb +136 -0
- data/lib/dripdrop/message.rb +26 -10
- data/lib/dripdrop/node.rb +103 -0
- metadata +45 -19
- data/bin/drip-mlogger +0 -8
- data/bin/drip-publisher +0 -8
- data/example/forwarder.cfg +0 -8
- data/example/web/public/js/jquery.gracefulWebSocket.js +0 -165
- data/example/web/public/js/jquery.js +0 -154
- data/example/web/public/js/jquery.websocket.js +0 -45
- data/example/web/public/view.html +0 -30
- data/example/web/server.rb +0 -11
- data/lib/dripdrop/collector.rb +0 -87
- data/lib/dripdrop/mlogger.rb +0 -35
- data/lib/dripdrop/publisher.rb +0 -53
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ffi-rzmq'
|
3
|
+
require 'zmqmachine'
|
4
|
+
require 'eventmachine'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
require 'dripdrop/message'
|
8
|
+
require 'dripdrop/handlers/zeromq'
|
9
|
+
require 'dripdrop/handlers/websockets'
|
10
|
+
|
11
|
+
class DripDrop
|
12
|
+
class Node
|
13
|
+
attr_reader :zm_reactor
|
14
|
+
attr_accessor :debug
|
15
|
+
|
16
|
+
def initialize(opts={},&block)
|
17
|
+
@handlers = {}
|
18
|
+
@debug = opts[:debug]
|
19
|
+
@recipients_for = {}
|
20
|
+
@handler_default_opts = {:debug => @debug}
|
21
|
+
@zm_reactor = nil
|
22
|
+
|
23
|
+
EM.run do
|
24
|
+
ZM::Reactor.new(:my_reactor).run do |zm_reactor|
|
25
|
+
@zm_reactor = zm_reactor
|
26
|
+
block.call(self)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def zmq_subscribe(address,socket_ctype,opts={},&block)
|
32
|
+
zm_addr = str_to_zm_address(address)
|
33
|
+
h_opts = handler_opts_given(opts)
|
34
|
+
handler = DripDrop::ZMQSubHandler.new(zm_addr,@zm_reactor,socket_ctype,h_opts)
|
35
|
+
@zm_reactor.sub_socket(handler)
|
36
|
+
handler
|
37
|
+
end
|
38
|
+
|
39
|
+
def zmq_publish(address,socket_ctype,opts={})
|
40
|
+
zm_addr = str_to_zm_address(address)
|
41
|
+
h_opts = handler_opts_given(opts)
|
42
|
+
handler = DripDrop::ZMQPubHandler.new(zm_addr,@zm_reactor,socket_ctype,h_opts)
|
43
|
+
@zm_reactor.pub_socket(handler)
|
44
|
+
handler
|
45
|
+
end
|
46
|
+
|
47
|
+
def zmq_pull(address,socket_ctype,opts={},&block)
|
48
|
+
zm_addr = str_to_zm_address(address)
|
49
|
+
h_opts = handler_opts_given(opts)
|
50
|
+
handler = DripDrop::ZMQPullHandler.new(zm_addr,@zm_reactor,socket_ctype,h_opts)
|
51
|
+
@zm_reactor.pull_socket(handler)
|
52
|
+
handler
|
53
|
+
end
|
54
|
+
|
55
|
+
def zmq_push(address,socket_ctype,opts={})
|
56
|
+
zm_addr = str_to_zm_address(address)
|
57
|
+
h_opts = handler_opts_given(opts)
|
58
|
+
handler = DripDrop::ZMQPushHandler.new(zm_addr,@zm_reactor,socket_ctype,h_opts)
|
59
|
+
@zm_reactor.push_socket(handler)
|
60
|
+
handler
|
61
|
+
end
|
62
|
+
|
63
|
+
def websocket(address,opts={},&block)
|
64
|
+
uri = URI.parse(address)
|
65
|
+
h_opts = handler_opts_given(opts)
|
66
|
+
handler = DripDrop::WebSocketHandler.new(uri,h_opts)
|
67
|
+
handler
|
68
|
+
end
|
69
|
+
|
70
|
+
def send_internal(dest,data)
|
71
|
+
return false unless @recipients_for[dest]
|
72
|
+
blocks = @recipients_for[dest].values
|
73
|
+
return false unless blocks
|
74
|
+
blocks.each do |block|
|
75
|
+
block.call(data)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def recv_internal(dest,identifier,&block)
|
80
|
+
if @recipients_for[dest]
|
81
|
+
@recipients_for[dest][identifier] = block
|
82
|
+
else
|
83
|
+
@recipients_for[dest] = {identifier => block}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def remove_recv_internal(dest,identifier)
|
88
|
+
return false unless @recipients_for[dest]
|
89
|
+
@recipients_for[dest].delete(identifier)
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def str_to_zm_address(str)
|
95
|
+
addr_uri = URI.parse(str)
|
96
|
+
ZM::Address.new(addr_uri.host,addr_uri.port.to_i,addr_uri.scheme.to_sym)
|
97
|
+
end
|
98
|
+
|
99
|
+
def handler_opts_given(opts)
|
100
|
+
@handler_default_opts.merge(opts)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dripdrop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
8
|
+
- 1
|
7
9
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.3
|
10
|
+
version: 0.1.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Andrew Cholakian
|
@@ -14,40 +15,69 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-09-05 00:00:00 -07:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
|
-
name:
|
22
|
+
name: ffi-rzmq
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
25
|
none: false
|
25
26
|
requirements:
|
26
27
|
- - ">="
|
27
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
28
30
|
segments:
|
29
31
|
- 0
|
30
32
|
version: "0"
|
31
33
|
type: :runtime
|
32
34
|
version_requirements: *id001
|
33
35
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
36
|
+
name: eventmachine
|
35
37
|
prerelease: false
|
36
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
37
39
|
none: false
|
38
40
|
requirements:
|
39
41
|
- - ">="
|
40
42
|
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
41
44
|
segments:
|
42
45
|
- 0
|
43
46
|
version: "0"
|
44
47
|
type: :runtime
|
45
48
|
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: bert
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: json
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :runtime
|
76
|
+
version_requirements: *id004
|
46
77
|
description: 0MQ App stats
|
47
78
|
email: andrew@andrewvc.com
|
48
|
-
executables:
|
49
|
-
|
50
|
-
- drip-publisher
|
79
|
+
executables: []
|
80
|
+
|
51
81
|
extensions: []
|
52
82
|
|
53
83
|
extra_rdoc_files:
|
@@ -60,23 +90,17 @@ files:
|
|
60
90
|
- README.md
|
61
91
|
- Rakefile
|
62
92
|
- VERSION
|
63
|
-
- bin/drip-mlogger
|
64
|
-
- bin/drip-publisher
|
65
93
|
- doc_img/topology.png
|
66
94
|
- dripdrop.gemspec
|
67
95
|
- example/agent_test.rb
|
68
|
-
- example/
|
69
|
-
- example/
|
70
|
-
- example/web/public/js/jquery.js
|
71
|
-
- example/web/public/js/jquery.websocket.js
|
72
|
-
- example/web/public/view.html
|
73
|
-
- example/web/server.rb
|
96
|
+
- example/pubsub.rb
|
97
|
+
- example/pushpull.rb
|
74
98
|
- lib/dripdrop.rb
|
75
99
|
- lib/dripdrop/agent.rb
|
76
|
-
- lib/dripdrop/
|
100
|
+
- lib/dripdrop/handlers/websockets.rb
|
101
|
+
- lib/dripdrop/handlers/zeromq.rb
|
77
102
|
- lib/dripdrop/message.rb
|
78
|
-
- lib/dripdrop/
|
79
|
-
- lib/dripdrop/publisher.rb
|
103
|
+
- lib/dripdrop/node.rb
|
80
104
|
has_rdoc: true
|
81
105
|
homepage: http://github.com/andrewvc/dripdrop
|
82
106
|
licenses: []
|
@@ -91,6 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
115
|
requirements:
|
92
116
|
- - ">="
|
93
117
|
- !ruby/object:Gem::Version
|
118
|
+
hash: 3
|
94
119
|
segments:
|
95
120
|
- 0
|
96
121
|
version: "0"
|
@@ -99,6 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
124
|
requirements:
|
100
125
|
- - ">="
|
101
126
|
- !ruby/object:Gem::Version
|
127
|
+
hash: 3
|
102
128
|
segments:
|
103
129
|
- 0
|
104
130
|
version: "0"
|
data/bin/drip-mlogger
DELETED
data/bin/drip-publisher
DELETED
data/example/forwarder.cfg
DELETED
@@ -1,165 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* WebSocket with graceful degradation - jQuery plugin
|
3
|
-
* @author David Lindkvist
|
4
|
-
* @version 0.1
|
5
|
-
*
|
6
|
-
* Returns an object implementing the WebSocket API.
|
7
|
-
*
|
8
|
-
* If browser supports WebSockets a native WebSocket instance is returned.
|
9
|
-
* If not, a simulated half-duplex implementation is returned which uses polling
|
10
|
-
* over HTTP to retrieve new messages
|
11
|
-
*
|
12
|
-
* OPTIONS
|
13
|
-
* -----------------------------------------------------------------------------
|
14
|
-
*
|
15
|
-
* {Number} fallbackOpenDelay number of ms to delay simulated open
|
16
|
-
* event for fallback
|
17
|
-
* {Number} fallbackPollInterval number of ms between requests for
|
18
|
-
* fallback polling
|
19
|
-
* {Object} fallbackPollParams optional params to pass with each poll
|
20
|
-
* requests
|
21
|
-
*
|
22
|
-
* EXAMPLES
|
23
|
-
* -----------------------------------------------------------------------------
|
24
|
-
*
|
25
|
-
* var websocket = $.gracefulWebSocket("ws://127.0.0.1:8080/");
|
26
|
-
*
|
27
|
-
* var websocket = $.gracefulWebSocket({
|
28
|
-
* fallbackPollParams: {
|
29
|
-
* "latestMessageID": function () {
|
30
|
-
* return latestMessageID;
|
31
|
-
* }
|
32
|
-
* }
|
33
|
-
* });
|
34
|
-
*
|
35
|
-
*/
|
36
|
-
|
37
|
-
(function ($) {
|
38
|
-
|
39
|
-
$.extend({
|
40
|
-
|
41
|
-
gracefulWebSocket: function (url, options) {
|
42
|
-
|
43
|
-
// Default properties
|
44
|
-
this.defaults = {
|
45
|
-
keepAlive: false, // not implemented - should ping server to keep socket open
|
46
|
-
autoReconnect: false, // not implemented - should try to reconnect silently if socket is closed
|
47
|
-
fallback: true, // not implemented - always use HTTP fallback if native browser support is missing
|
48
|
-
fallbackSendURL: url.replace('ws:', 'http:').replace('wss:', 'https:'),
|
49
|
-
fallbackSendMethod: 'POST',
|
50
|
-
fallbackPollURL: url.replace('ws:', 'http:').replace('wss:', 'https:'),
|
51
|
-
fallbackPollMethod: 'GET',
|
52
|
-
fallbackOpenDelay: 100, // number of ms to delay simulated open event
|
53
|
-
fallbackPollInterval: 3000, // number of ms between poll requests
|
54
|
-
fallbackPollParams: {} // optional params to pass with poll requests
|
55
|
-
};
|
56
|
-
|
57
|
-
// Override defaults with user properties
|
58
|
-
var opts = $.extend({}, this.defaults, options);
|
59
|
-
|
60
|
-
/**
|
61
|
-
* Creates a fallback object implementing the WebSocket interface
|
62
|
-
*/
|
63
|
-
function FallbackSocket() {
|
64
|
-
|
65
|
-
// WebSocket interface constants
|
66
|
-
const CONNECTING = 0;
|
67
|
-
const OPEN = 1;
|
68
|
-
const CLOSING = 2;
|
69
|
-
const CLOSED = 3;
|
70
|
-
|
71
|
-
var pollInterval;
|
72
|
-
var openTimout;
|
73
|
-
|
74
|
-
// create WebSocket object
|
75
|
-
var fws = {
|
76
|
-
// ready state
|
77
|
-
readyState: CONNECTING,
|
78
|
-
bufferedAmount: 0,
|
79
|
-
send: function (data) {
|
80
|
-
var success = true;
|
81
|
-
$.ajax({
|
82
|
-
async: false, // send synchronously
|
83
|
-
type: opts.fallbackSendMethod,
|
84
|
-
url: opts.fallbackSendURL + '?' + $.param( getFallbackParams() ),
|
85
|
-
data: data,
|
86
|
-
dataType: 'text',
|
87
|
-
contentType : "application/x-www-form-urlencoded; charset=utf-8",
|
88
|
-
success: pollSuccess,
|
89
|
-
error: function (xhr) {
|
90
|
-
success = false;
|
91
|
-
$(fws).triggerHandler('error');
|
92
|
-
}
|
93
|
-
});
|
94
|
-
return success;
|
95
|
-
},
|
96
|
-
close: function () {
|
97
|
-
clearTimeout(openTimout);
|
98
|
-
clearInterval(pollInterval);
|
99
|
-
this.readyState = CLOSED;
|
100
|
-
$(fws).triggerHandler('close');
|
101
|
-
},
|
102
|
-
onopen: function () {},
|
103
|
-
onmessage: function () {},
|
104
|
-
onerror: function () {},
|
105
|
-
onclose: function () {},
|
106
|
-
previousRequest: null,
|
107
|
-
currentRequest: null
|
108
|
-
};
|
109
|
-
|
110
|
-
function getFallbackParams() {
|
111
|
-
|
112
|
-
// update timestamp of previous and current poll request
|
113
|
-
fws.previousRequest = fws.currentRequest;
|
114
|
-
fws.currentRequest = new Date().getTime();
|
115
|
-
|
116
|
-
// extend default params with plugin options
|
117
|
-
return $.extend({"previousRequest": fws.previousRequest, "currentRequest": fws.currentRequest}, opts.fallbackPollParams);
|
118
|
-
}
|
119
|
-
|
120
|
-
/**
|
121
|
-
* @param {Object} data
|
122
|
-
*/
|
123
|
-
function pollSuccess(data) {
|
124
|
-
|
125
|
-
// trigger onmessage
|
126
|
-
var messageEvent = {"data" : data};
|
127
|
-
fws.onmessage(messageEvent);
|
128
|
-
}
|
129
|
-
|
130
|
-
function poll() {
|
131
|
-
|
132
|
-
$.ajax({
|
133
|
-
type: opts.fallbackPollMethod,
|
134
|
-
url: opts.fallbackPollURL,
|
135
|
-
dataType: 'text',
|
136
|
-
data: getFallbackParams(),
|
137
|
-
success: pollSuccess,
|
138
|
-
error: function (xhr) {
|
139
|
-
$(fws).triggerHandler('error');
|
140
|
-
}
|
141
|
-
});
|
142
|
-
}
|
143
|
-
|
144
|
-
// simulate open event and start polling
|
145
|
-
openTimout = setTimeout(function () {
|
146
|
-
fws.readyState = OPEN;
|
147
|
-
//fws.currentRequest = new Date().getTime();
|
148
|
-
$(fws).triggerHandler('open');
|
149
|
-
poll();
|
150
|
-
pollInterval = setInterval(poll, opts.fallbackPollInterval);
|
151
|
-
|
152
|
-
}, opts.fallbackOpenDelay);
|
153
|
-
|
154
|
-
// return socket impl
|
155
|
-
return fws;
|
156
|
-
}
|
157
|
-
|
158
|
-
// create a new websocket or fallback
|
159
|
-
var ws = window.WebSocket ? new WebSocket(url) : new FallbackSocket();
|
160
|
-
$(window).unload(function () { ws.close(); ws = null });
|
161
|
-
return ws;
|
162
|
-
}
|
163
|
-
});
|
164
|
-
|
165
|
-
})(jQuery);
|