firehose 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/polleverywhere/firehose.png)](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
|