firehose 1.1.0 → 1.1.1
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/.travis.yml +5 -0
- data/README.md +2 -0
- data/Rakefile +7 -1
- data/firehose.gemspec +6 -5
- data/lib/assets/flash/firehose/WebSocketMainInsecure.swf +0 -0
- data/lib/firehose/assets.rb +11 -1
- data/lib/firehose/producer.rb +13 -3
- data/lib/firehose/subscriber.rb +4 -4
- data/lib/firehose/version.rb +2 -2
- data/spec/integrations/integration_test_helper.rb +6 -0
- data/spec/integrations/rainbows_spec.rb +1 -1
- data/spec/integrations/shared_examples.rb +7 -2
- data/spec/integrations/thin_spec.rb +1 -1
- data/spec/lib/producer_spec.rb +13 -1
- data/spec/lib/publisher_spec.rb +1 -1
- data/spec/lib/subscriber_spec.rb +1 -1
- metadata +30 -12
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -7,6 +7,8 @@
|
|
7
7
|
|
8
8
|
Build realtime web applications in Ruby and JS
|
9
9
|
|
10
|
+
[](https://travis-ci.org/polleverywhere/firehose)
|
11
|
+
|
10
12
|
# What is Firehose?
|
11
13
|
|
12
14
|
Firehose is both a Rack application and JavaScript library that makes building real-time web applications possible.
|
data/Rakefile
CHANGED
data/firehose.gemspec
CHANGED
@@ -19,12 +19,12 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
21
|
# specify any dependencies here; for example:
|
22
|
-
s.add_runtime_dependency "eventmachine", ">= 1.0.0
|
23
|
-
s.add_runtime_dependency "em-hiredis"
|
22
|
+
s.add_runtime_dependency "eventmachine", ">= 1.0.0"
|
23
|
+
s.add_runtime_dependency "em-hiredis", ">= 0.2.0"
|
24
24
|
s.add_runtime_dependency "thor"
|
25
25
|
s.add_runtime_dependency "faraday"
|
26
26
|
s.add_runtime_dependency "faye-websocket"
|
27
|
-
s.add_runtime_dependency "em-http-request", "
|
27
|
+
s.add_runtime_dependency "em-http-request", ">= 1.0.0"
|
28
28
|
s.add_runtime_dependency "json"
|
29
29
|
|
30
30
|
s.add_development_dependency "rspec"
|
@@ -32,10 +32,11 @@ Gem::Specification.new do |s|
|
|
32
32
|
s.add_development_dependency "guard-rspec"
|
33
33
|
s.add_development_dependency "guard-bundler"
|
34
34
|
s.add_development_dependency "guard-coffeescript"
|
35
|
-
s.add_development_dependency "rainbows"
|
35
|
+
s.add_development_dependency "rainbows", "~> 4.4.3"
|
36
36
|
s.add_development_dependency "thin"
|
37
37
|
s.add_development_dependency "rack-test"
|
38
38
|
s.add_development_dependency "async_rack_test"
|
39
39
|
s.add_development_dependency "foreman"
|
40
40
|
s.add_development_dependency "sprockets"
|
41
|
-
|
41
|
+
s.add_development_dependency "rake"
|
42
|
+
end
|
Binary file
|
data/lib/firehose/assets.rb
CHANGED
@@ -19,6 +19,16 @@ module Firehose
|
|
19
19
|
Firehose::Assets::Sprockets.configure ::Sprockets
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
def self.manifest
|
24
|
+
paths = []
|
25
|
+
|
26
|
+
paths << Firehose::Assets.path('/flash/firehose/WebSocketMainInsecure.swf')
|
27
|
+
|
28
|
+
paths << File.basename(Firehose::Assets.path('/javascripts/firehose/firehose.js.coffee'), '.coffee')
|
29
|
+
|
30
|
+
paths
|
31
|
+
end
|
22
32
|
end
|
23
33
|
end
|
24
|
-
end
|
34
|
+
end
|
data/lib/firehose/producer.rb
CHANGED
@@ -44,7 +44,17 @@ module Firehose
|
|
44
44
|
|
45
45
|
response = conn.put do |req|
|
46
46
|
req.options[:timeout] = Timeout
|
47
|
-
|
47
|
+
if conn.path_prefix.nil? || conn.path_prefix == '/'
|
48
|
+
# This avoids a double / if the channel starts with a / too (which is expected).
|
49
|
+
req.path = channel
|
50
|
+
else
|
51
|
+
if conn.path_prefix =~ /\/\Z/ || channel =~ /\A\//
|
52
|
+
req.path = [conn.path_prefix, channel].compact.join
|
53
|
+
else
|
54
|
+
# Add a / so the prefix and channel aren't just rammed together.
|
55
|
+
req.path = [conn.path_prefix, channel].compact.join('/')
|
56
|
+
end
|
57
|
+
end
|
48
58
|
req.body = message
|
49
59
|
req.headers['Cache-Control'] = "max-age=#{ttl.to_i}" if ttl
|
50
60
|
end
|
@@ -84,11 +94,11 @@ module Firehose
|
|
84
94
|
end
|
85
95
|
|
86
96
|
private
|
87
|
-
# Build out a Faraday connection
|
97
|
+
# Build out a Faraday connection
|
88
98
|
def conn
|
89
99
|
@conn ||= Faraday.new(:url => uri.to_s) do |builder|
|
90
100
|
builder.adapter self.class.adapter
|
91
101
|
end
|
92
102
|
end
|
93
103
|
end
|
94
|
-
end
|
104
|
+
end
|
data/lib/firehose/subscriber.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
module Firehose
|
2
2
|
# Setups a connetion to Redis to listen for new resources...
|
3
3
|
class Subscriber
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :pubsub
|
5
5
|
|
6
6
|
def initialize(redis)
|
7
|
-
@
|
7
|
+
@pubsub = redis.pubsub
|
8
8
|
|
9
9
|
# TODO: Instead of just raising an exception, it would probably be better
|
10
10
|
# for the errback to set some sort of 'disconnected' state. Then
|
@@ -16,10 +16,10 @@ module Firehose
|
|
16
16
|
# with the same error.
|
17
17
|
# The final goal is to allow the failed deferrable bubble back up
|
18
18
|
# so we can send back a nice, clean 500 error to the client.
|
19
|
-
|
19
|
+
pubsub.subscribe('firehose:channel_updates').
|
20
20
|
errback{|e| EM.next_tick { raise e } }.
|
21
21
|
callback { Firehose.logger.debug "Redis subscribed to `firehose:channel_updates`" }
|
22
|
-
|
22
|
+
pubsub.on(:message) do |_, payload|
|
23
23
|
channel_key, sequence, message = Firehose::Publisher.from_payload(payload)
|
24
24
|
|
25
25
|
if deferrables = subscriptions.delete(channel_key)
|
data/lib/firehose/version.rb
CHANGED
@@ -22,7 +22,6 @@ shared_examples_for 'Firehose::Rack::App' do
|
|
22
22
|
let(:app) { Firehose::Rack::App.new }
|
23
23
|
let(:messages) { (1..2000).map{|n| "msg-#{n}" } }
|
24
24
|
let(:channel) { "/firehose/integration/#{Time.now.to_i}" }
|
25
|
-
let(:uri) { Firehose::Default::URI }
|
26
25
|
let(:http_url) { "http://#{uri.host}:#{uri.port}#{channel}" }
|
27
26
|
let(:ws_url) { "ws://#{uri.host}:#{uri.port}#{channel}" }
|
28
27
|
|
@@ -68,8 +67,14 @@ shared_examples_for 'Firehose::Rack::App' do
|
|
68
67
|
# And test a web socket client too, at the same time.
|
69
68
|
websocket = Proc.new do |cid|
|
70
69
|
ws = Faye::WebSocket::Client.new(ws_url)
|
70
|
+
|
71
|
+
ws.onopen = lambda do |event|
|
72
|
+
ws.send('{"message_sequence":0}')
|
73
|
+
end
|
74
|
+
|
71
75
|
ws.onmessage = lambda do |event|
|
72
|
-
|
76
|
+
frame = JSON.parse(event.data, :symbolize_names => true)
|
77
|
+
received[cid] << frame[:message]
|
73
78
|
succeed.call cid unless received[cid].size < messages.size
|
74
79
|
end
|
75
80
|
|
data/spec/lib/producer_spec.rb
CHANGED
@@ -21,6 +21,18 @@ describe Firehose::Producer do
|
|
21
21
|
WebMock.should have_requested(:put, url).with { |req| req.body == message }
|
22
22
|
end
|
23
23
|
|
24
|
+
context 'prefix is specified in URI' do
|
25
|
+
let(:firehose_uri) {"#{Firehose::Default::URI}/prefix"}
|
26
|
+
let(:url) { "#{firehose_uri}#{channel}"}
|
27
|
+
|
28
|
+
it "should publish message to channel" do
|
29
|
+
publish_stub.to_return(:body => "", :status => 202)
|
30
|
+
|
31
|
+
Firehose::Producer.new(firehose_uri).publish(message).to(channel)
|
32
|
+
WebMock.should have_requested(:put, url).with { |req| req.body == message }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
24
36
|
it "should publish message to channel with expiry headers" do
|
25
37
|
publish_stub.to_return(:body => "", :status => 202)
|
26
38
|
ttl = 20
|
@@ -56,4 +68,4 @@ describe Firehose::Producer do
|
|
56
68
|
}.should raise_exception(Firehose::Producer::TimeoutError)
|
57
69
|
end
|
58
70
|
end
|
59
|
-
end
|
71
|
+
end
|
data/spec/lib/publisher_spec.rb
CHANGED
@@ -18,7 +18,7 @@ describe Firehose::Publisher do
|
|
18
18
|
describe "#publish" do
|
19
19
|
it "should publish message change" do
|
20
20
|
em do
|
21
|
-
hiredis = EM::Hiredis.connect
|
21
|
+
hiredis = EM::Hiredis.connect.pubsub
|
22
22
|
hiredis.subscribe "firehose:channel_updates"
|
23
23
|
hiredis.on(:message) {|_, msg|
|
24
24
|
msg.should == "#{channel_key}\n1\n#{message}"
|
data/spec/lib/subscriber_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe Firehose::Subscriber do
|
|
5
5
|
|
6
6
|
let(:channel_key) { '/bears/are/mean' }
|
7
7
|
let(:subscriber) { Firehose::Subscriber.new(EM::Hiredis.connect) }
|
8
|
-
let(:dummy_subscriber){ Firehose::Subscriber.new(double('redis', :subscribe => EM::DefaultDeferrable.new, :on => nil)) }
|
8
|
+
let(:dummy_subscriber){ Firehose::Subscriber.new(double('redis', :pubsub => double('pubsub', :subscribe => EM::DefaultDeferrable.new, :on => nil))) }
|
9
9
|
let(:message) { 'Raaaarrrrrr!!!!' }
|
10
10
|
let(:publisher) { Firehose::Publisher.new }
|
11
11
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: firehose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2013-04-20 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: eventmachine
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
requirements:
|
22
22
|
- - ! '>='
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: 1.0.0
|
24
|
+
version: 1.0.0
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 1.0.0
|
32
|
+
version: 1.0.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: em-hiredis
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -37,7 +37,7 @@ dependencies:
|
|
37
37
|
requirements:
|
38
38
|
- - ! '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 0.2.0
|
41
41
|
type: :runtime
|
42
42
|
prerelease: false
|
43
43
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -45,7 +45,7 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - ! '>='
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
48
|
+
version: 0.2.0
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: thor
|
51
51
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,7 +99,7 @@ dependencies:
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
none: false
|
101
101
|
requirements:
|
102
|
-
- -
|
102
|
+
- - ! '>='
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
version: 1.0.0
|
105
105
|
type: :runtime
|
@@ -107,7 +107,7 @@ dependencies:
|
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
none: false
|
109
109
|
requirements:
|
110
|
-
- -
|
110
|
+
- - ! '>='
|
111
111
|
- !ruby/object:Gem::Version
|
112
112
|
version: 1.0.0
|
113
113
|
- !ruby/object:Gem::Dependency
|
@@ -211,17 +211,17 @@ dependencies:
|
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
212
212
|
none: false
|
213
213
|
requirements:
|
214
|
-
- -
|
214
|
+
- - ~>
|
215
215
|
- !ruby/object:Gem::Version
|
216
|
-
version:
|
216
|
+
version: 4.4.3
|
217
217
|
type: :development
|
218
218
|
prerelease: false
|
219
219
|
version_requirements: !ruby/object:Gem::Requirement
|
220
220
|
none: false
|
221
221
|
requirements:
|
222
|
-
- -
|
222
|
+
- - ~>
|
223
223
|
- !ruby/object:Gem::Version
|
224
|
-
version:
|
224
|
+
version: 4.4.3
|
225
225
|
- !ruby/object:Gem::Dependency
|
226
226
|
name: thin
|
227
227
|
requirement: !ruby/object:Gem::Requirement
|
@@ -302,6 +302,22 @@ dependencies:
|
|
302
302
|
- - ! '>='
|
303
303
|
- !ruby/object:Gem::Version
|
304
304
|
version: '0'
|
305
|
+
- !ruby/object:Gem::Dependency
|
306
|
+
name: rake
|
307
|
+
requirement: !ruby/object:Gem::Requirement
|
308
|
+
none: false
|
309
|
+
requirements:
|
310
|
+
- - ! '>='
|
311
|
+
- !ruby/object:Gem::Version
|
312
|
+
version: '0'
|
313
|
+
type: :development
|
314
|
+
prerelease: false
|
315
|
+
version_requirements: !ruby/object:Gem::Requirement
|
316
|
+
none: false
|
317
|
+
requirements:
|
318
|
+
- - ! '>='
|
319
|
+
- !ruby/object:Gem::Version
|
320
|
+
version: '0'
|
305
321
|
description: Firehose is a realtime web application toolkit for building realtime
|
306
322
|
Ruby web applications.
|
307
323
|
email:
|
@@ -318,6 +334,7 @@ files:
|
|
318
334
|
- .gitignore
|
319
335
|
- .rbenv-version
|
320
336
|
- .rspec
|
337
|
+
- .travis.yml
|
321
338
|
- Gemfile
|
322
339
|
- Guardfile
|
323
340
|
- Procfile
|
@@ -327,6 +344,7 @@ files:
|
|
327
344
|
- config/rainbows.rb
|
328
345
|
- firehose.gemspec
|
329
346
|
- lib/assets/flash/firehose/WebSocketMain.swf
|
347
|
+
- lib/assets/flash/firehose/WebSocketMainInsecure.swf
|
330
348
|
- lib/assets/javascripts/firehose.js.coffee
|
331
349
|
- lib/assets/javascripts/firehose/base.js.coffee
|
332
350
|
- lib/assets/javascripts/firehose/consumer.js.coffee
|