firehose 0.0.10 → 0.0.11

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.
@@ -1,6 +1,7 @@
1
1
  require 'firehose/version'
2
2
 
3
3
  require 'amqp'
4
+ require 'logger'
4
5
 
5
6
  module Firehose
6
7
  autoload :Subscription, 'firehose/subscription'
@@ -20,4 +21,13 @@ module Firehose
20
21
  def self.reset!
21
22
  @amqp = nil
22
23
  end
24
+
25
+ # Logging
26
+ def self.logger
27
+ @logger ||= Logger.new($stdout)
28
+ end
29
+
30
+ def self.logger=(logger)
31
+ @logger = logger
32
+ end
23
33
  end
@@ -5,6 +5,7 @@ module Firehose
5
5
  exchange = AMQP::Exchange.new(channel, :fanout, path, :auto_delete => true)
6
6
  # TODO How do I clean up this exchange at this point? Do I close it somehow or the channel?
7
7
  # The exchange just hangs out indefinitely now.
8
+ Firehose.logger.debug "AMQP publishing `#{message}` to `#{path}`"
8
9
  exchange.publish(message)
9
10
  exchange.delete(:if_unused => true)
10
11
  end
@@ -21,8 +21,6 @@ module Firehose
21
21
  # GET is how clients subscribe to the queue. When a messages comes in, we flush out a response,
22
22
  # close down the requeust, and the client then reconnects.
23
23
  when 'GET'
24
- p [:subscribed, cid, path]
25
-
26
24
  EM.next_tick do
27
25
  # Setup a subscription with a client id. We haven't subscribed yet here.
28
26
  subscription = Firehose::Subscription.new(cid)
@@ -32,24 +30,24 @@ module Firehose
32
30
  timer = EM.add_timer(timeout) do
33
31
  # We send a 204 OK to tell the client to reconnect.
34
32
  env['async.callback'].call [204, cors_headers, []]
35
- p [:timeout]
33
+ Firehose.logger.debug "HTTP wait `#{cid}@#{path}` timed out"
36
34
  end
37
35
 
38
36
  # Ok, now subscribe to the subscription.
39
- subscription.subscribe path do |payload|
37
+ subscription.subscribe path do |message|
40
38
  subscription.unsubscribe
41
39
  subscription = nil # Set this to nil so that our heart beat timer doesn't try to double unsub.
42
40
  EM.cancel_timer timer # Turn off the heart beat so we don't execute any of that business.
43
- env['async.callback'].call [200, cors_headers, [payload]]
41
+ env['async.callback'].call [200, cors_headers, [message]]
42
+ Firehose.logger.debug "HTTP sent `#{message}` to `#{cid}@#{path}`"
44
43
  end
44
+ Firehose.logger.debug "HTTP subscribed to `#{cid}@#{path}`"
45
45
 
46
46
  # Unsubscribe from the subscription if its still open and something bad happened
47
47
  # or the heart beat triggered before we could finish.
48
48
  env['async.close'].callback do
49
- if subscription
50
- subscription.unsubscribe
51
- p [:close_unsubscription]
52
- end
49
+ subscription.unsubscribe if subscription
50
+ Firehose.logger.debug "HTTP connection `#{cid}@#{path}` closing"
53
51
  end
54
52
  end
55
53
 
@@ -59,36 +57,43 @@ module Firehose
59
57
  # PUT is how we throw messages on to the fan-out queue.
60
58
  when 'PUT'
61
59
  body = env['rack.input'].read
62
- p [:put, path, body]
60
+ Firehose.logger.debug "HTTP published `#{body}` to `#{path}`"
63
61
  Firehose::Publisher.new.publish(path, body)
64
62
 
65
63
  [202, {}, []]
66
64
  else
65
+ Firehose.logger.debug "HTTP #{method} not supported"
67
66
  [501, {'Content-Type' => 'text/plain'}, ["#{method} not supported."]]
68
67
  end
69
68
  end
70
69
  end
71
70
 
72
71
  class WebSocket < ::Rack::WebSocket::Application
72
+ attr_reader :cid, :path
73
+
73
74
  # Subscribe to a path and make some magic happen, mmkmay?
74
75
  def on_open(env)
75
76
  req = ::Rack::Request.new(env)
76
- cid = req.params['cid']
77
- path = req.path
77
+ @cid = req.params['cid']
78
+ @path = req.path
78
79
 
79
80
  @subscription = Firehose::Subscription.new(cid)
80
- @subscription.subscribe path do |payload|
81
- send_data payload
81
+ @subscription.subscribe path do |message|
82
+ Firehose.logger.debug "WS sent `#{message}` to `#{cid}@#{path}`"
83
+ send_data message
82
84
  end
85
+ Firehose.logger.debug "WS subscribed to `#{cid}@#{path}`"
83
86
  end
84
87
 
85
88
  # Delete the subscription if the thing even happened.
86
89
  def on_close(env)
87
90
  @subscription.unsubscribe if @subscription
91
+ Firehose.logger.debug "WS connection `#{cid}@#{path}` closing"
88
92
  end
89
93
 
90
94
  # Log websocket level errors
91
95
  def on_error(env, error)
96
+ Firehose.logger.error "WS connection `#{cid}@#{path}` error `#{error}`: #{env.inspect}"
92
97
  @subscription.unsubscribe if @subscription
93
98
  end
94
99
  end
@@ -14,6 +14,8 @@ module Firehose
14
14
  @subscriber_id = subscriber_id || self.class.subscriber_id
15
15
  end
16
16
 
17
+ # TODO - Move the path to an initializer so that we can force on AMQP subscription per one
18
+ # Firehose subscription. As it stands now, you could fire off multple subscriptions to diff channels
17
19
  def subscribe(path, &block)
18
20
  queue_name = "#{subscriber_id}@#{path}"
19
21
  channel = AMQP::Channel.new(Firehose.amqp.connection).prefetch(1)
@@ -25,16 +27,18 @@ module Firehose
25
27
  # ttl starts ticking down. On the reconnect, the consumer connects to the queue and resets the
26
28
  # timer on x-expires... in theory at least.
27
29
  @consumer = AMQP::Consumer.new(channel, queue, subscriber_id)
28
- @consumer.on_delivery do |metadata, payload|
29
- p [:get, subscriber_id, @consumer.consumer_tag, path, payload]
30
- block.call(payload)
30
+ @consumer.on_delivery do |metadata, message|
31
+ Firehose.logger.debug "AMQP delivering `#{message}` to `#{subscriber_id}@#{path}`"
32
+ block.call(message)
31
33
  # The ack needs to go after the block is called. This makes sure that all processing
32
34
  # happens downstream before we remove it from the queue entirely.
33
35
  metadata.ack
34
36
  end.consume
37
+ Firehose.logger.debug "AMQP subscribed to `#{subscriber_id}@#{path}`"
35
38
  end
36
39
 
37
40
  def unsubscribe
41
+ Firehose.logger.debug "AMQP unsubscribed"
38
42
  @consumer.cancel if @consumer
39
43
  end
40
44
 
@@ -1,4 +1,4 @@
1
1
  module Firehose
2
- VERSION = "0.0.10"
3
- CODENAME = "Garden Hose"
2
+ VERSION = "0.0.11"
3
+ CODENAME = "Shouty Shamous"
4
4
  end
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: 0.0.10
4
+ version: 0.0.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -14,7 +14,7 @@ date: 2012-04-28 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: eventmachine
17
- requirement: &70248892020200 !ruby/object:Gem::Requirement
17
+ requirement: &70308648263700 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 1.0.0.beta
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70248892020200
25
+ version_requirements: *70308648263700
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: amqp
28
- requirement: &70248892017640 !ruby/object:Gem::Requirement
28
+ requirement: &70308648262880 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 0.9.4
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70248892017640
36
+ version_requirements: *70308648262880
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: thin
39
- requirement: &70248892031220 !ruby/object:Gem::Requirement
39
+ requirement: &70308648261900 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *70248892031220
47
+ version_requirements: *70308648261900
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: thor
50
- requirement: &70248892024520 !ruby/object:Gem::Requirement
50
+ requirement: &70308648260860 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '0'
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *70248892024520
58
+ version_requirements: *70308648260860
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: websocket-rack
61
- requirement: &70248892039500 !ruby/object:Gem::Requirement
61
+ requirement: &70308648260100 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: '0'
67
67
  type: :runtime
68
68
  prerelease: false
69
- version_requirements: *70248892039500
69
+ version_requirements: *70308648260100
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: faraday
72
- requirement: &70248892037240 !ruby/object:Gem::Requirement
72
+ requirement: &70308648258940 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: '0'
78
78
  type: :runtime
79
79
  prerelease: false
80
- version_requirements: *70248892037240
80
+ version_requirements: *70308648258940
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: rspec
83
- requirement: &70248892032840 !ruby/object:Gem::Requirement
83
+ requirement: &70308648258020 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,10 +88,10 @@ dependencies:
88
88
  version: '0'
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *70248892032840
91
+ version_requirements: *70308648258020
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: rack-test
94
- requirement: &70248892042160 !ruby/object:Gem::Requirement
94
+ requirement: &70308648257080 !ruby/object:Gem::Requirement
95
95
  none: false
96
96
  requirements:
97
97
  - - ! '>='
@@ -99,10 +99,10 @@ dependencies:
99
99
  version: '0'
100
100
  type: :development
101
101
  prerelease: false
102
- version_requirements: *70248892042160
102
+ version_requirements: *70308648257080
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: guard-rspec
105
- requirement: &70248892053200 !ruby/object:Gem::Requirement
105
+ requirement: &70308648271320 !ruby/object:Gem::Requirement
106
106
  none: false
107
107
  requirements:
108
108
  - - ! '>='
@@ -110,10 +110,10 @@ dependencies:
110
110
  version: '0'
111
111
  type: :development
112
112
  prerelease: false
113
- version_requirements: *70248892053200
113
+ version_requirements: *70308648271320
114
114
  - !ruby/object:Gem::Dependency
115
115
  name: guard-bundler
116
- requirement: &70248892049780 !ruby/object:Gem::Requirement
116
+ requirement: &70308648267980 !ruby/object:Gem::Requirement
117
117
  none: false
118
118
  requirements:
119
119
  - - ! '>='
@@ -121,10 +121,10 @@ dependencies:
121
121
  version: '0'
122
122
  type: :development
123
123
  prerelease: false
124
- version_requirements: *70248892049780
124
+ version_requirements: *70308648267980
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: em-http-request
127
- requirement: &70248892059480 !ruby/object:Gem::Requirement
127
+ requirement: &70308648266640 !ruby/object:Gem::Requirement
128
128
  none: false
129
129
  requirements:
130
130
  - - ~>
@@ -132,10 +132,10 @@ dependencies:
132
132
  version: 0.3.0
133
133
  type: :development
134
134
  prerelease: false
135
- version_requirements: *70248892059480
135
+ version_requirements: *70308648266640
136
136
  - !ruby/object:Gem::Dependency
137
137
  name: guard-coffeescript
138
- requirement: &70248892071480 !ruby/object:Gem::Requirement
138
+ requirement: &70308648265120 !ruby/object:Gem::Requirement
139
139
  none: false
140
140
  requirements:
141
141
  - - ! '>='
@@ -143,7 +143,7 @@ dependencies:
143
143
  version: '0'
144
144
  type: :development
145
145
  prerelease: false
146
- version_requirements: *70248892071480
146
+ version_requirements: *70308648265120
147
147
  description: Firehose is a realtime web application toolkit for building realtime
148
148
  Ruby web applications.
149
149
  email: