message_bus 2.0.0.beta.6 → 2.0.0.beta.7
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.
Potentially problematic release.
This version of message_bus might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG +7 -0
- data/README.md +11 -1
- data/assets/message-bus.js +4 -0
- data/examples/chat/chat.rb +1 -4
- data/examples/chat/docker_container/chat.yml +23 -1
- data/lib/message_bus.rb +44 -9
- data/lib/message_bus/backends/postgres.rb +3 -5
- data/lib/message_bus/version.rb +1 -1
- data/spec/assets/SpecHelper.js +6 -2
- data/spec/assets/message-bus.spec.js +13 -0
- data/spec/lib/message_bus_spec.rb +22 -0
- data/vendor/assets/javascripts/message-bus-ajax.js +44 -0
- data/vendor/assets/javascripts/message-bus.js +4 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 765d5f2c439f0bcc0ca030a838d93510ed638916
|
4
|
+
data.tar.gz: 23a0428b2f62625e4063c066828d9fb5925a0a86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19127a42396bebe0d047fc7a3c41d7be908072711ef294e71d4f6546acd260b93520a4d0eb391d39b63253b5d6e057ee43aebaf7e032dd8f6cc6531352131001
|
7
|
+
data.tar.gz: e863e48441974a73d3f956b9ba2cf01622bbc173ac5db435d3b0c1d38db0dab9b2b884d230cf50ab463ec225d323a73f4a7fd0299a033940074b5aaf29bb6583
|
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -49,6 +49,16 @@ MessageBus.subscribe "/channel" do |msg|
|
|
49
49
|
# block called in a background thread when message is received
|
50
50
|
end
|
51
51
|
|
52
|
+
# subscribe to channel and receive the entire backlog
|
53
|
+
MessageBus.subscribe "/channel", 0 do |msg|
|
54
|
+
# block called in a background thread when message is received
|
55
|
+
end
|
56
|
+
|
57
|
+
# subscribe to channel and receive the backlog starting at message 6
|
58
|
+
MessageBus.subscribe "/channel", 5 do |msg|
|
59
|
+
# block called in a background thread when message is received
|
60
|
+
end
|
61
|
+
|
52
62
|
MessageBus.backlog "/channel", id
|
53
63
|
# returns all messages after the id
|
54
64
|
|
@@ -175,7 +185,7 @@ maxPollInterval|180000|If request to the server start failing, MessageBus will b
|
|
175
185
|
alwaysLongPoll|false|For debugging you may want to disable the "is browser in background" check and always long-poll
|
176
186
|
baseUrl|/|If message bus is mounted in a subdirectory of different domain, you may configure it to perform requests there
|
177
187
|
ajax|$.ajax or XMLHttpRequest|MessageBus will first attempt to use jQuery and then fallback to a plain XMLHttpRequest version that's contained in the `messsage-bus-ajax.js` file. `messsage-bus-ajax.js` must be loaded after `messsage-bus.js` for it to be used.
|
178
|
-
|
188
|
+
headers|{}|Extra headers to be include with request. Properties and values of object must be valid values for HTTP Headers, i.e. no spaces and control characters.
|
179
189
|
**API**:
|
180
190
|
|
181
191
|
`MessageBus.diagnostics()` : Returns a log that may be used for diagnostics on the status of message bus
|
data/assets/message-bus.js
CHANGED
@@ -123,6 +123,9 @@
|
|
123
123
|
var headers = {
|
124
124
|
'X-SILENCE-LOGGER': 'true'
|
125
125
|
};
|
126
|
+
for (var name in me.headers){
|
127
|
+
headers[name] = me.headers[name];
|
128
|
+
}
|
126
129
|
|
127
130
|
if (!chunked){
|
128
131
|
headers["Dont-Chunk"] = 'true';
|
@@ -274,6 +277,7 @@
|
|
274
277
|
clientId: clientId,
|
275
278
|
alwaysLongPoll: false,
|
276
279
|
baseUrl: baseUrl,
|
280
|
+
headers: {},
|
277
281
|
ajax: (jQuery && jQuery.ajax),
|
278
282
|
noConflict: function(){
|
279
283
|
global.MessageBus = global.MessageBus.previousMessageBus;
|
data/examples/chat/chat.rb
CHANGED
@@ -121,10 +121,7 @@ class Chat < Sinatra::Base
|
|
121
121
|
$(function() {
|
122
122
|
var name;
|
123
123
|
|
124
|
-
MessageBus.
|
125
|
-
args["headers"]["X-NAME"] = name;
|
126
|
-
return $.ajax(args);
|
127
|
-
};
|
124
|
+
MessageBus.headers["X-NAME"] = name;
|
128
125
|
|
129
126
|
var enter = function(name, opts) {
|
130
127
|
if (opts && opts.check) {
|
@@ -2,6 +2,7 @@ base_image: "discourse/base:1.0.15"
|
|
2
2
|
|
3
3
|
update_pups: false
|
4
4
|
|
5
|
+
|
5
6
|
params:
|
6
7
|
home: /var/www/message_bus
|
7
8
|
|
@@ -10,11 +11,15 @@ templates:
|
|
10
11
|
|
11
12
|
expose:
|
12
13
|
- "80:80"
|
14
|
+
- "443:443"
|
13
15
|
|
14
16
|
volumes:
|
15
17
|
- volume:
|
16
18
|
host: /var/docker/shared/chat
|
17
19
|
guest: /shared
|
20
|
+
- volume:
|
21
|
+
host: /etc/letsencrypt
|
22
|
+
guest: /etc/letsencrypt
|
18
23
|
|
19
24
|
hooks:
|
20
25
|
after_redis:
|
@@ -45,6 +50,10 @@ hooks:
|
|
45
50
|
filename: /etc/nginx/nginx.conf
|
46
51
|
from: pid /run/nginx.pid;
|
47
52
|
to: daemon off;
|
53
|
+
- exec:
|
54
|
+
cmd:
|
55
|
+
- "mkdir -p /shared/ssl"
|
56
|
+
- "[ -e /shared/ssl/dhparams.pem ] || openssl dhparam -out /shared/ssl/dhparams.pem 2048"
|
48
57
|
- file:
|
49
58
|
path: /etc/nginx/conf.d/chat.conf
|
50
59
|
contents: |
|
@@ -53,11 +62,25 @@ hooks:
|
|
53
62
|
}
|
54
63
|
server {
|
55
64
|
listen 80;
|
65
|
+
rewrite ^ https://chat.samsaffron.com$request_uri? permanent;
|
66
|
+
}
|
67
|
+
server {
|
68
|
+
listen 443 ssl http2;
|
69
|
+
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
70
|
+
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
|
71
|
+
ssl_prefer_server_ciphers on;
|
72
|
+
ssl_session_tickets off;
|
73
|
+
ssl_session_timeout 1d;
|
74
|
+
ssl_session_cache shared:SSL:1m;
|
75
|
+
ssl_dhparam /shared/ssl/dhparams.pem;
|
76
|
+
ssl_certificate /etc/letsencrypt/live/chat.samsaffron.com/fullchain.pem;
|
77
|
+
ssl_certificate_key /etc/letsencrypt/live/chat.samsaffron.com/privkey.pem;
|
56
78
|
gzip on;
|
57
79
|
gzip_types application/json text/css application/x-javascript;
|
58
80
|
gzip_min_length 1000;
|
59
81
|
server_name chat.samsaffron.com;
|
60
82
|
keepalive_timeout 65;
|
83
|
+
root /shared/letsencrypt;
|
61
84
|
|
62
85
|
location /message-bus/ {
|
63
86
|
proxy_set_header Host $http_host;
|
@@ -70,7 +93,6 @@ hooks:
|
|
70
93
|
break;
|
71
94
|
}
|
72
95
|
|
73
|
-
|
74
96
|
location / {
|
75
97
|
try_files $uri @chat;
|
76
98
|
break;
|
data/lib/message_bus.rb
CHANGED
@@ -257,8 +257,14 @@ module MessageBus::Implementation
|
|
257
257
|
channel.split(ENCODE_SITE_TOKEN)
|
258
258
|
end
|
259
259
|
|
260
|
-
def subscribe(channel=nil, &blk)
|
261
|
-
subscribe_impl(channel, nil, &blk)
|
260
|
+
def subscribe(channel=nil, last_id=-1, &blk)
|
261
|
+
subscribe_impl(channel, nil, last_id, &blk)
|
262
|
+
end
|
263
|
+
|
264
|
+
# subscribe only on current site
|
265
|
+
def local_subscribe(channel=nil, last_id=-1, &blk)
|
266
|
+
site_id = site_id_lookup.call if site_id_lookup && ! global?(channel)
|
267
|
+
subscribe_impl(channel, site_id, last_id, &blk)
|
262
268
|
end
|
263
269
|
|
264
270
|
def unsubscribe(channel=nil, &blk)
|
@@ -270,12 +276,6 @@ module MessageBus::Implementation
|
|
270
276
|
unsubscribe_impl(channel, site_id, &blk)
|
271
277
|
end
|
272
278
|
|
273
|
-
# subscribe only on current site
|
274
|
-
def local_subscribe(channel=nil, &blk)
|
275
|
-
site_id = site_id_lookup.call if site_id_lookup && ! global?(channel)
|
276
|
-
subscribe_impl(channel, site_id, &blk)
|
277
|
-
end
|
278
|
-
|
279
279
|
def global_backlog(last_id=nil)
|
280
280
|
backlog(nil, last_id)
|
281
281
|
end
|
@@ -372,10 +372,45 @@ module MessageBus::Implementation
|
|
372
372
|
msg.client_ids = parsed["client_ids"]
|
373
373
|
end
|
374
374
|
|
375
|
-
def
|
375
|
+
def replay_backlog(channel, last_id, site_id)
|
376
|
+
id = nil
|
377
|
+
|
378
|
+
backlog(channel, last_id, site_id).each do |m|
|
379
|
+
yield m
|
380
|
+
id = m.message_id
|
381
|
+
end
|
382
|
+
|
383
|
+
id
|
384
|
+
end
|
385
|
+
|
386
|
+
def subscribe_impl(channel, site_id, last_id, &blk)
|
376
387
|
|
377
388
|
raise MessageBus::BusDestroyed if @destroyed
|
378
389
|
|
390
|
+
if last_id >= 0
|
391
|
+
# this gets a bit tricky, but we got to ensure ordering so we wrap the block
|
392
|
+
original_blk = blk
|
393
|
+
current_id = replay_backlog(channel, last_id, site_id, &blk)
|
394
|
+
just_yield = false
|
395
|
+
|
396
|
+
# we double check to ensure no messages snuck through while we were subscribing
|
397
|
+
blk = proc do |m|
|
398
|
+
if just_yield
|
399
|
+
original_blk.call m
|
400
|
+
else
|
401
|
+
if current_id && current_id == (m.message_id-1)
|
402
|
+
original_blk.call m
|
403
|
+
just_yield = true
|
404
|
+
else
|
405
|
+
current_id = replay_backlog(channel, current_id, site_id, &original_blk)
|
406
|
+
if (current_id == m.id)
|
407
|
+
just_yield = true
|
408
|
+
end
|
409
|
+
end
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
379
414
|
@subscriptions ||= {}
|
380
415
|
@subscriptions[site_id] ||= {}
|
381
416
|
@subscriptions[site_id][channel] ||= []
|
@@ -52,11 +52,11 @@ class MessageBus::Postgres::Client
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def backlog(channel, backlog_id)
|
55
|
-
hold{|conn| exec_prepared(conn, 'channel_backlog', [channel, backlog_id]){|r| r.values.each{|a| a[0] = a[0].to_i}}}
|
55
|
+
hold{|conn| exec_prepared(conn, 'channel_backlog', [channel, backlog_id]){|r| r.values.each{|a| a[0] = a[0].to_i}}} || []
|
56
56
|
end
|
57
57
|
|
58
58
|
def global_backlog(backlog_id)
|
59
|
-
hold{|conn| exec_prepared(conn, 'global_backlog', [backlog_id]){|r| r.values.each{|a| a[0] = a[0].to_i}}}
|
59
|
+
hold{|conn| exec_prepared(conn, 'global_backlog', [backlog_id]){|r| r.values.each{|a| a[0] = a[0].to_i}}} || []
|
60
60
|
end
|
61
61
|
|
62
62
|
def get_value(channel, id)
|
@@ -157,7 +157,7 @@ class MessageBus::Postgres::Client
|
|
157
157
|
conn = sync{@available.shift} || new_pg_connection
|
158
158
|
sync{@allocated[Thread.current] = conn}
|
159
159
|
yield conn
|
160
|
-
rescue PG::ConnectionBad => e
|
160
|
+
rescue PG::ConnectionBad, PG::UnableToSend => e
|
161
161
|
# don't add this connection back to the pool
|
162
162
|
ensure
|
163
163
|
sync{@allocated.delete(Thread.current)}
|
@@ -279,8 +279,6 @@ class MessageBus::Postgres::ReliablePubSub
|
|
279
279
|
end
|
280
280
|
|
281
281
|
def global_backlog(last_id = nil)
|
282
|
-
last_id = last_id.to_i
|
283
|
-
|
284
282
|
items = client.global_backlog last_id.to_i
|
285
283
|
|
286
284
|
items.map! do |id, channel, data|
|
data/lib/message_bus/version.rb
CHANGED
data/spec/assets/SpecHelper.js
CHANGED
@@ -24,7 +24,9 @@ var encodeChunks = function(xhr, chunks) {
|
|
24
24
|
beforeEach(function () {
|
25
25
|
var spec = this;
|
26
26
|
|
27
|
-
function MockedXMLHttpRequest(
|
27
|
+
function MockedXMLHttpRequest(){
|
28
|
+
this.headers = {};
|
29
|
+
};
|
28
30
|
MockedXMLHttpRequest.prototype.send = function(){
|
29
31
|
this.readyState = 4
|
30
32
|
this.responseText = encodeChunks(this, spec.responseChunks);
|
@@ -35,7 +37,9 @@ beforeEach(function () {
|
|
35
37
|
}
|
36
38
|
MockedXMLHttpRequest.prototype.open = function(){ }
|
37
39
|
MockedXMLHttpRequest.prototype.abort = function(){ }
|
38
|
-
MockedXMLHttpRequest.prototype.setRequestHeader = function(){
|
40
|
+
MockedXMLHttpRequest.prototype.setRequestHeader = function(k,v){
|
41
|
+
this.headers[k] = v;
|
42
|
+
}
|
39
43
|
MockedXMLHttpRequest.prototype.getResponseHeader = function(){
|
40
44
|
return 'text/plain; charset=utf-8';
|
41
45
|
}
|
@@ -74,4 +74,17 @@ describe("Messagebus", function() {
|
|
74
74
|
window.MessageBus = mb;
|
75
75
|
});
|
76
76
|
|
77
|
+
testMB('sends using custom header', function(){
|
78
|
+
MessageBus.headers['X-MB-TEST-VALUE'] = '42';
|
79
|
+
this.perform(function(message, xhr){
|
80
|
+
expect(xhr.headers).toEqual({
|
81
|
+
'X-SILENCE-LOGGER': 'true',
|
82
|
+
'X-MB-TEST-VALUE': '42',
|
83
|
+
'Content-Type': 'application/json'
|
84
|
+
});
|
85
|
+
}).finally(function(){
|
86
|
+
MessageBus.headers = {};
|
87
|
+
})
|
88
|
+
});
|
89
|
+
|
77
90
|
});
|
@@ -18,6 +18,28 @@ describe MessageBus do
|
|
18
18
|
@bus.destroy
|
19
19
|
end
|
20
20
|
|
21
|
+
it "can subscribe from a point in time" do
|
22
|
+
@bus.publish("/minion", "banana")
|
23
|
+
|
24
|
+
data1 = []
|
25
|
+
data2 = []
|
26
|
+
|
27
|
+
@bus.subscribe("/minion") do |msg|
|
28
|
+
data1 << msg.data
|
29
|
+
end
|
30
|
+
|
31
|
+
@bus.subscribe("/minion", 0) do |msg|
|
32
|
+
data2 << msg.data
|
33
|
+
end
|
34
|
+
|
35
|
+
@bus.publish("/minion", "bananana")
|
36
|
+
|
37
|
+
wait_for(2000){ data2.length == 2 && data1.length == 1}
|
38
|
+
|
39
|
+
data1.must_equal ['bananana']
|
40
|
+
data2.must_equal ['banana', 'bananana']
|
41
|
+
end
|
42
|
+
|
21
43
|
it "can transmit client_ids" do
|
22
44
|
client_ids = nil
|
23
45
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
// A bare-bones implementation of $.ajax that MessageBus will use
|
2
|
+
// as a fallback if jQuery is not present
|
3
|
+
//
|
4
|
+
// Only implements methods & options used by MessageBus
|
5
|
+
(function(global, undefined) {
|
6
|
+
'use strict';
|
7
|
+
if (!global.MessageBus){
|
8
|
+
throw new Error("MessageBus must be loaded before the ajax adapter");
|
9
|
+
}
|
10
|
+
|
11
|
+
var cacheBuster = Math.random() * 10000 | 0;
|
12
|
+
|
13
|
+
global.MessageBus.ajax = function(options){
|
14
|
+
var XHRImpl = (global.MessageBus && global.MessageBus.xhrImplementation) || global.XMLHttpRequest;
|
15
|
+
var xhr = new XHRImpl();
|
16
|
+
xhr.dataType = options.dataType;
|
17
|
+
var url = options.url;
|
18
|
+
if (!options.cache){
|
19
|
+
url += ((-1 == url.indexOf('?')) ? '?' : '&') + '_=' + (cacheBuster++)
|
20
|
+
}
|
21
|
+
xhr.open('POST', url);
|
22
|
+
for (var name in options.headers){
|
23
|
+
xhr.setRequestHeader(name, options.headers[name]);
|
24
|
+
}
|
25
|
+
xhr.setRequestHeader('Content-Type', 'application/json');
|
26
|
+
if (options.messageBus.chunked){
|
27
|
+
options.messageBus.onProgressListener(xhr);
|
28
|
+
}
|
29
|
+
xhr.onreadystatechange = function(){
|
30
|
+
if (xhr.readyState === 4){
|
31
|
+
var status = xhr.status;
|
32
|
+
if (status >= 200 && status < 300 || status === 304){
|
33
|
+
options.success(xhr.responseText);
|
34
|
+
} else {
|
35
|
+
options.error(xhr, xhr.statusText);
|
36
|
+
}
|
37
|
+
options.complete();
|
38
|
+
}
|
39
|
+
}
|
40
|
+
xhr.send(JSON.stringify(options.data));
|
41
|
+
return xhr;
|
42
|
+
};
|
43
|
+
|
44
|
+
})(window);
|
@@ -123,6 +123,9 @@
|
|
123
123
|
var headers = {
|
124
124
|
'X-SILENCE-LOGGER': 'true'
|
125
125
|
};
|
126
|
+
for (var name in me.headers){
|
127
|
+
headers[name] = me.headers[name];
|
128
|
+
}
|
126
129
|
|
127
130
|
if (!chunked){
|
128
131
|
headers["Dont-Chunk"] = 'true';
|
@@ -274,6 +277,7 @@
|
|
274
277
|
clientId: clientId,
|
275
278
|
alwaysLongPoll: false,
|
276
279
|
baseUrl: baseUrl,
|
280
|
+
headers: {},
|
277
281
|
ajax: (jQuery && jQuery.ajax),
|
278
282
|
noConflict: function(){
|
279
283
|
global.MessageBus = global.MessageBus.previousMessageBus;
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: message_bus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.beta.
|
4
|
+
version: 2.0.0.beta.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -131,6 +131,7 @@ files:
|
|
131
131
|
- spec/lib/message_bus/timer_thread_spec.rb
|
132
132
|
- spec/lib/message_bus_spec.rb
|
133
133
|
- spec/spec_helper.rb
|
134
|
+
- vendor/assets/javascripts/message-bus-ajax.js
|
134
135
|
- vendor/assets/javascripts/message-bus.js
|
135
136
|
homepage: https://github.com/SamSaffron/message_bus
|
136
137
|
licenses:
|