celluloid_pubsub 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e96840919322edc81e5d6e77deb8579ad2a41f1d
4
- data.tar.gz: 998c3da9bff6142d543e170a6c17a37703206ec8
3
+ metadata.gz: 1fd09c4be6a3a41e2e10ee14717df60bda21a008
4
+ data.tar.gz: 105b47986bcb0bcbb31a71e34a742218f8fb2836
5
5
  SHA512:
6
- metadata.gz: 8c9c48887e176e1be23baf62bd328fc6af00d0607f725c4d1039650b74e627fa2dac00da6474406b8e06c65588f4e31056822bc215f22dd09d7d978e331f3185
7
- data.tar.gz: d2556fb35ab937cfe303db592b198d5068b545fe141b735aae929f5d021da012aa84e8c55ffbe1a90cb742a182df79c4ac42f3ab4e717e4ccc411ff4fea72491
6
+ metadata.gz: e5b28bc53a3a2a947ffa64a969e61baef8792937708103d89b2b46e4d4aaba6a57029ef05791d133481ae8e465d5cfc237a5c1ccb9b365e24f356f2a21c5721b
7
+ data.tar.gz: 3635b6499fca2e4a2b950629d01fc0503474f8953033de53655d5656e995fb6c37d9b578df5acf727fc777f7590832b64385b5d3b54b1b59855eba8b169d299a
data/README.md CHANGED
@@ -8,7 +8,7 @@ Description
8
8
 
9
9
  CelluloidPubsub is a simple ruby implementation of publish subscribe design patterns using celluloid actors and websockets, using Celluloid::Reel server
10
10
 
11
- Starting with version 0.4.0, Redis support was added [courtesy of em-hiredis](https://github.com/mloughran/em-hiredis)
11
+ Starting with version 0.6.0, Redis support was moved into gem [celluloid_pubsub_redis_adapter](https://github.com/bogdanRada/celluloid_pubsub_redis_adapter)
12
12
 
13
13
  Requirements
14
14
  ------------
@@ -20,8 +20,7 @@ Requirements
20
20
  5. [http >= 1.0.2](https://github.com/httprb/http)
21
21
  6. [Celluloid-websocket-client = 0.0.1](https://github.com/jeremyd/celluloid-websocket-client)
22
22
  7. [ActiveSuport >= 4.2.0](https://rubygems.org/gems/activesupport)
23
- 8. [em-hiredis >= 0.3.0](https://github.com/mloughran/em-hiredis)
24
- 9. [json >= 1.8.3](https://github.com/flori/json)
23
+ 8. [json >= 1.8.3](https://github.com/flori/json)
25
24
 
26
25
  Compatibility
27
26
  -------------
@@ -51,7 +50,7 @@ Creating a websocket server is simple as doing this. This are all the options av
51
50
  ```ruby
52
51
  CelluloidPubsub::WebServer.supervise_as(:web_server,
53
52
  enable_debug: true, # if debug messages should be logged
54
- use_redis: false , # if set to true, will instantiate a RedisReactor class to handle each connection, which requires Redis to be available. Otherwise will use a simple Reactor to handle the connections which has no dependencies .
53
+ adapter: nil , # if set to nil, will instantiate a simple Reactor to handle the connections which has no dependencies . Otherwise will try to use that adapter. Please see [celluloid_pubsub_redis_adapter](https://github.com/bogdanRada/celluloid_pubsub_redis_adapter) for more details on using redis adapter
55
54
  log_file_path: "path/to/log_file.log", # The log file where all debugging information will be printed
56
55
  hostname: "0.0.0.0", # the hostname of the server.
57
56
  port: 1234, # the port on which the server will listen for connections
@@ -22,9 +22,9 @@ Gem::Specification.new do |s|
22
22
  s.add_runtime_dependency 'http', '~> 1.0', '>= 1.0.2'
23
23
  s.add_runtime_dependency 'celluloid-websocket-client', '~> 0.0', '>= 0.0.1'
24
24
  s.add_runtime_dependency 'activesupport', '~> 4.1', '>= 4.1.0'
25
- s.add_runtime_dependency 'em-hiredis', '~> 0.3', '>= 0.3.0'
26
25
  s.add_runtime_dependency 'json', '~> 1.8', '>= 1.8.3'
27
26
 
27
+
28
28
  s.add_development_dependency 'rspec', '~> 3.4', '>= 3.4'
29
29
  s.add_development_dependency 'simplecov', '~> 0.10', '>= 0.10'
30
30
  s.add_development_dependency 'simplecov-summary', '~> 0.0.4', '>= 0.0.4'
@@ -1,2 +1,71 @@
1
- ENV['USE_REDIS'] = 'false'
2
- require_relative './shared_classes'
1
+ require 'bundler/setup'
2
+ require 'celluloid_pubsub'
3
+ require 'logger'
4
+
5
+ debug_enabled = ENV['DEBUG'].present? && ENV['DEBUG'].to_s == 'true'
6
+ log_file_path = File.join(File.expand_path(File.dirname(__FILE__)), 'log', 'celluloid_pubsub.log')
7
+
8
+ # actor that subscribes to a channel
9
+ class FirstActor
10
+ include Celluloid
11
+ include Celluloid::Logger
12
+
13
+ def initialize(options = {})
14
+ @client = CelluloidPubsub::Client.new({ actor: Actor.current, channel: 'test_channel' }.merge(options))
15
+ end
16
+
17
+ def on_message(message)
18
+ if @client.succesfull_subscription?(message)
19
+ puts "subscriber got successful subscription #{message.inspect}"
20
+ @client.publish('test_channel2', 'data' => ' subscriber got successfull subscription') # the message needs to be a Hash
21
+ else
22
+ puts "subscriber got message #{message.inspect}"
23
+ end
24
+ end
25
+
26
+ def on_close(code, reason)
27
+ puts "websocket connection closed: #{code.inspect}, #{reason.inspect}"
28
+ terminate
29
+ end
30
+
31
+
32
+ end
33
+
34
+ # actor that publishes a message in a channel
35
+ class SecondActor
36
+ include Celluloid
37
+ include Celluloid::Logger
38
+
39
+ def initialize(options = {})
40
+ @client = CelluloidPubsub::Client.new({ actor: Actor.current, channel: 'test_channel2' }.merge(options))
41
+ end
42
+
43
+ def on_message(message)
44
+ if @client.succesfull_subscription?(message)
45
+ puts "publisher got successful subscription #{message.inspect}"
46
+ @client.publish('test_channel', 'data' => ' my_message') # the message needs to be a Hash
47
+ else
48
+ puts "publisher got message #{message.inspect}"
49
+ end
50
+ end
51
+
52
+ def on_close(code, reason)
53
+ puts "websocket connection closed: #{code.inspect}, #{reason.inspect}"
54
+ terminate
55
+ end
56
+
57
+ end
58
+
59
+
60
+ CelluloidPubsub::WebServer.supervise_as(:web_server, enable_debug: debug_enabled, adapter: nil,log_file_path: log_file_path )
61
+ FirstActor.supervise_as(:first_actor, enable_debug: debug_enabled)
62
+ SecondActor.supervise_as(:second_actor, enable_debug: debug_enabled)
63
+ signal_received = false
64
+
65
+ Signal.trap('INT') do
66
+ puts "\nAn interrupt signal has been triggered!"
67
+ signal_received = true
68
+ end
69
+
70
+ puts 'Exited succesfully! =)'
71
+ sleep 0.1 until signal_received
@@ -270,7 +270,7 @@ module CelluloidPubsub
270
270
  return unless channel.present?
271
271
  add_subscriber_to_channel(channel, message)
272
272
  log_debug "#{self.class} subscribed to #{channel} with #{message}"
273
- @websocket << message.merge('client_action' => 'successful_subscription', 'channel' => channel).to_json unless @server.redis_enabled?
273
+ @websocket << message.merge('client_action' => 'successful_subscription', 'channel' => channel).to_json if @server.adapter == CelluloidPubsub::WebServer::CLASSIC_ADAPTER
274
274
  end
275
275
 
276
276
  # this method will return a list of all subscribers to a particular channel or a empty array
@@ -15,9 +15,9 @@ module CelluloidPubsub
15
15
  # major release version
16
16
  MAJOR = 0
17
17
  # minor release version
18
- MINOR = 5
18
+ MINOR = 6
19
19
  # tiny release version
20
- TINY = 2
20
+ TINY = 0
21
21
  # prelease version ( set this only if it is a prelease)
22
22
  PRE = nil
23
23
 
@@ -23,6 +23,8 @@ module CelluloidPubsub
23
23
  PORT = 1234
24
24
  # The request path that the webserver accepts by default
25
25
  PATH = '/ws'
26
+ # The name of the default adapter
27
+ CLASSIC_ADAPTER = 'classic'
26
28
 
27
29
  attr_accessor :server_options, :subscribers
28
30
  finalizer :shutdown
@@ -59,8 +61,9 @@ module CelluloidPubsub
59
61
  # @return [Boolean] return true if redis can be used otherwise false
60
62
  #
61
63
  # @api public
62
- def use_redis
63
- @use_redis = @server_options.fetch('use_redis', false)
64
+ def adapter
65
+ @adapter ||= @server_options.fetch('adapter', CelluloidPubsub::WebServer::CLASSIC_ADAPTER)
66
+ @adapter.present? ? @adapter : CelluloidPubsub::WebServer::CLASSIC_ADAPTER
64
67
  end
65
68
 
66
69
  # the method will return true if debug is enabled otherwise false
@@ -145,15 +148,6 @@ module CelluloidPubsub
145
148
  @backlog = @server_options.fetch('backlog', 1024)
146
149
  end
147
150
 
148
- # the method will return true if redis is enabled otherwise false
149
- #
150
- #
151
- # @return [Boolean] returns true if redis is enabled otherwise false
152
- #
153
- # @api public
154
- def redis_enabled?
155
- use_redis.to_s.downcase == 'true'
156
- end
157
151
 
158
152
  # callback that will execute when receiving new conections
159
153
  # If the connections is a websocket will call method {#route_websocket}
@@ -196,7 +190,7 @@ module CelluloidPubsub
196
190
  #
197
191
  # @api public
198
192
  def reactor_class
199
- redis_enabled? ? CelluloidPubsub::RedisReactor : CelluloidPubsub::Reactor
193
+ adapter == CelluloidPubsub::WebServer::CLASSIC_ADAPTER ? CelluloidPubsub::Reactor : "CelluloidPubsub::#{adapter.camelize}Reactor".constantize
200
194
  end
201
195
 
202
196
  # method will instantiate a new reactor object, will link the reactor to the current actor and will dispatch the request to the reactor
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: celluloid_pubsub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - bogdanRada
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-19 00:00:00.000000000 Z
11
+ date: 2016-02-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid
@@ -130,26 +130,6 @@ dependencies:
130
130
  - - ">="
131
131
  - !ruby/object:Gem::Version
132
132
  version: 4.1.0
133
- - !ruby/object:Gem::Dependency
134
- name: em-hiredis
135
- requirement: !ruby/object:Gem::Requirement
136
- requirements:
137
- - - "~>"
138
- - !ruby/object:Gem::Version
139
- version: '0.3'
140
- - - ">="
141
- - !ruby/object:Gem::Version
142
- version: 0.3.0
143
- type: :runtime
144
- prerelease: false
145
- version_requirements: !ruby/object:Gem::Requirement
146
- requirements:
147
- - - "~>"
148
- - !ruby/object:Gem::Version
149
- version: '0.3'
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: 0.3.0
153
133
  - !ruby/object:Gem::Dependency
154
134
  name: json
155
135
  requirement: !ruby/object:Gem::Requirement
@@ -391,8 +371,6 @@ files:
391
371
  - README.md
392
372
  - Rakefile
393
373
  - celluloid_pubsub.gemspec
394
- - examples/redis_test.rb
395
- - examples/shared_classes.rb
396
374
  - examples/simple_test.rb
397
375
  - init.rb
398
376
  - lib/celluloid_pubsub.rb
@@ -400,7 +378,6 @@ files:
400
378
  - lib/celluloid_pubsub/helper.rb
401
379
  - lib/celluloid_pubsub/initializers/reel_colors.rb
402
380
  - lib/celluloid_pubsub/reactor.rb
403
- - lib/celluloid_pubsub/redis_reactor.rb
404
381
  - lib/celluloid_pubsub/registry.rb
405
382
  - lib/celluloid_pubsub/version.rb
406
383
  - lib/celluloid_pubsub/web_server.rb
@@ -1,2 +0,0 @@
1
- ENV['USE_REDIS'] = 'true'
2
- require_relative './shared_classes'
@@ -1,72 +0,0 @@
1
- require 'bundler/setup'
2
- require 'celluloid_pubsub'
3
- require 'logger'
4
-
5
- debug_enabled = ENV['DEBUG'].present? && ENV['DEBUG'].to_s == 'true'
6
- use_redis = ENV['USE_REDIS'].present? && ENV['USE_REDIS'].to_s == 'true'
7
- log_file_path = File.join(File.expand_path(File.dirname(__FILE__)), 'log', 'celluloid_pubsub.log')
8
-
9
- # actor that subscribes to a channel
10
- class Subscriber
11
- include Celluloid
12
- include Celluloid::Logger
13
-
14
- def initialize(options = {})
15
- @client = CelluloidPubsub::Client.new({ actor: Actor.current, channel: 'test_channel' }.merge(options))
16
- end
17
-
18
- def on_message(message)
19
- if @client.succesfull_subscription?(message)
20
- puts "subscriber got successful subscription #{message.inspect}"
21
- @client.publish('test_channel2', 'data' => ' subscriber got successfull subscription') # the message needs to be a Hash
22
- else
23
- puts "subscriber got message #{message.inspect}"
24
- end
25
- end
26
-
27
- def on_close(code, reason)
28
- puts "websocket connection closed: #{code.inspect}, #{reason.inspect}"
29
- terminate
30
- end
31
-
32
-
33
- end
34
-
35
- # actor that publishes a message in a channel
36
- class Publisher
37
- include Celluloid
38
- include Celluloid::Logger
39
-
40
- def initialize(options = {})
41
- @client = CelluloidPubsub::Client.new({ actor: Actor.current, channel: 'test_channel2' }.merge(options))
42
- end
43
-
44
- def on_message(message)
45
- if @client.succesfull_subscription?(message)
46
- puts "publisher got successful subscription #{message.inspect}"
47
- @client.publish('test_channel', 'data' => ' my_message') # the message needs to be a Hash
48
- else
49
- puts "publisher got message #{message.inspect}"
50
- end
51
- end
52
-
53
- def on_close(code, reason)
54
- puts "websocket connection closed: #{code.inspect}, #{reason.inspect}"
55
- terminate
56
- end
57
-
58
- end
59
-
60
-
61
- CelluloidPubsub::WebServer.supervise_as(:web_server, enable_debug: debug_enabled, use_redis: use_redis,log_file_path: log_file_path )
62
- Subscriber.supervise_as(:subscriber, enable_debug: debug_enabled)
63
- Publisher.supervise_as(:publisher, enable_debug: debug_enabled)
64
- signal_received = false
65
-
66
- Signal.trap('INT') do
67
- puts "\nAn interrupt signal has been triggered!"
68
- signal_received = true
69
- end
70
-
71
- sleep 0.1 until signal_received
72
- puts 'Exited succesfully! =)'
@@ -1,282 +0,0 @@
1
- require_relative './reactor'
2
- require_relative './helper'
3
- module CelluloidPubsub
4
- # reactor used for redis pubsub
5
- # @!attribute connected
6
- # @return [Boolean] returns true if already connected to redis
7
- # @!attribute connection
8
- # @return [EM::Hiredis] The connection used for redis
9
- class RedisReactor < CelluloidPubsub::Reactor
10
- include Celluloid
11
- include Celluloid::IO
12
- include Celluloid::Logger
13
- include CelluloidPubsub::Helper
14
-
15
- attr_accessor :connected, :connection
16
-
17
- alias_method :connected?, :connected
18
-
19
- # returns true if already connected to redis otherwise false
20
- #
21
- # @return [Boolean] returns true if already connected to redis otherwise false
22
- #
23
- # @api public
24
- def connected
25
- @connected ||= false
26
- end
27
-
28
- # method used to unsubscribe from a channel
29
- # @see #redis_action
30
- #
31
- # @return [void]
32
- #
33
- # @api public
34
- def unsubscribe(channel)
35
- super
36
- async.redis_action('unsubscribe', channel)
37
- end
38
-
39
- # method used to subscribe to a channel
40
- # @see #redis_action
41
- #
42
- # @return [void]
43
- #
44
- # @api public
45
- def add_subscriber_to_channel(channel, message)
46
- super
47
- async.redis_action('subscribe', channel, message)
48
- end
49
-
50
- # method used to unsubscribe from a channel
51
- # @see #redis_action
52
- #
53
- # @return [void]
54
- #
55
- # @api public
56
- def unsubscribe_from_channel(channel)
57
- super
58
- async.redis_action('unsubscribe', channel)
59
- end
60
-
61
- # method used to unsubscribe from all channels
62
- # @see #redis_action
63
- #
64
- # @return [void]
65
- #
66
- # @api public
67
- def unsubscribe_all
68
- info 'clearing connections'
69
- shutdown
70
- end
71
-
72
- # method used to shutdown the reactor and unsubscribe from all channels
73
- # @see #redis_action
74
- #
75
- # @return [void]
76
- #
77
- # @api public
78
- def shutdown
79
- @channels.dup.each do |channel|
80
- redis_action('unsubscribe', channel)
81
- end if @channels.present?
82
- super
83
- end
84
-
85
- # method used to publish event using redis
86
- #
87
- # @return [void]
88
- #
89
- # @api public
90
- def publish_event(topic, data)
91
- return if topic.blank? || data.blank?
92
- connect_to_redis do |connection|
93
- connection.publish(topic, data)
94
- end
95
- rescue => exception
96
- log_debug("could not publish message #{message} into topic #{current_topic} because of #{exception.inspect}")
97
- end
98
-
99
- private
100
-
101
- # method used to run the enventmachine and setup the exception handler
102
- # @see #run_the_eventmachine
103
- # @see #setup_em_exception_handler
104
- #
105
- # @param [Proc] block the block that will use the connection
106
- #
107
- # @return [void]
108
- #
109
- # @api private
110
- def connect_to_redis(&block)
111
- require 'eventmachine'
112
- require 'em-hiredis'
113
- run_the_eventmachine(&block)
114
- setup_em_exception_handler
115
- end
116
-
117
- # method used to connect to redis and yield the connection
118
- #
119
- # @param [Proc] block the block that will use the connection
120
- #
121
- # @return [void]
122
- #
123
- # @api private
124
- def run_the_eventmachine(&block)
125
- EM.run do
126
- @connection ||= EM::Hiredis.connect
127
- @connected = true
128
- block.call @connection
129
- end
130
- end
131
-
132
- # method used to setup the eventmachine exception handler
133
- #
134
- # @return [void]
135
- #
136
- # @api private
137
- def setup_em_exception_handler
138
- EM.error_handler do |error|
139
- debug error unless filtered_error?(error)
140
- end
141
- end
142
-
143
- # method used to fetch the pubsub client from the connection and yield it
144
- #
145
- # @return [void]
146
- #
147
- # @api private
148
- def fetch_pubsub
149
- connect_to_redis do |connection|
150
- @pubsub ||= connection.pubsub
151
- yield @pubsub if block_given?
152
- end
153
- end
154
-
155
- # method used to fetch the pubsub client from the connection and yield it
156
- # @see #action_subscribe
157
- #
158
- # @param [string] action The action that will be checked
159
- # @param [string] channel The channel that reactor has subscribed to
160
- # @param [string] message The initial message used to subscribe
161
- #
162
- # @return [void]
163
- #
164
- # @api private
165
- def action_success(action, channel, message)
166
- action_subscribe?(action) ? message.merge('client_action' => 'successful_subscription', 'channel' => channel) : nil
167
- end
168
-
169
- # method used execute an action (subscribe or unsubscribe ) to redis
170
- # @see #prepare_redis_action
171
- # @see #action_success
172
- # @see #register_subscription_callbacks
173
- #
174
- # @param [string] action The action that will be checked
175
- # @param [string] channel The channel that reactor has subscribed to
176
- # @param [string] message The initial message used to subscribe
177
- #
178
- # @return [void]
179
- #
180
- # @api private
181
- def redis_action(action, channel = nil, message = {})
182
- fetch_pubsub do |pubsub|
183
- callback = prepare_redis_action(pubsub, action)
184
- success_message = action_success(action, channel, message)
185
- args = action_subscribe?(action) ? [channel, callback] : [channel]
186
- subscription = pubsub.send(action, *args)
187
- register_subscription_callbacks(subscription, action, success_message)
188
- end
189
- end
190
-
191
- # method used check if the action is subscribe and write the incoming message to be websocket or log the message otherwise
192
- # @see #log_unsubscriptions
193
- # @see #action_subscribe
194
- #
195
- # @param [String] action The action that will be checked if it is subscribed
196
- #
197
- # @return [void]
198
- #
199
- # @api private
200
- def prepare_redis_action(pubsub, action)
201
- log_unsubscriptions(pubsub)
202
- proc do |subscribed_message|
203
- action_subscribe?(action) ? (@websocket << subscribed_message) : log_debug(message)
204
- end
205
- end
206
-
207
- # method used to listen to unsubscriptions and log them to log file
208
- # @see #register_redis_callback
209
- # @see #register_redis_error_callback
210
- #
211
- # @param [EM::Hiredis::PubsubClient] pubsub The pubsub client that will be used to listen to unsubscriptions
212
- #
213
- # @return [void]
214
- #
215
- # @api private
216
- def log_unsubscriptions(pubsub)
217
- pubsub.on(:unsubscribe) do |subscribed_channel, remaining_subscriptions|
218
- log_debug [:unsubscribe_happened, subscribed_channel, remaining_subscriptions].inspect
219
- end
220
- end
221
-
222
- # method used registers the sucess and error callabacks
223
- # @see #register_redis_callback
224
- # @see #register_redis_error_callback
225
- #
226
- # @param [EM::DefaultDeferrable] subscription The subscription object
227
- # @param [string] action The action that will be checked
228
- # @param [string] sucess_message The initial message used to subscribe
229
- #
230
- # @return [void]
231
- #
232
- # @api private
233
- def register_subscription_callbacks(subscription, action, sucess_message = nil)
234
- register_redis_callback(subscription, action, sucess_message)
235
- register_redis_error_callback(subscription, action)
236
- end
237
-
238
- # the method will return true if debug is enabled
239
- #
240
- #
241
- # @return [Boolean] returns true if debug is enabled otherwise false
242
- #
243
- # @api public
244
- def debug_enabled?
245
- @server.debug_enabled?
246
- end
247
-
248
- # method used to register a success callback and if action is subscribe will write
249
- # back to the websocket a message that will say it is a successful_subscription
250
- # If action is something else, will log the incoming message
251
- # @see #log_debug
252
- #
253
- # @param [EM::DefaultDeferrable] subscription The subscription object
254
- # @param [string] sucess_message The initial message used to subscribe
255
- #
256
- # @return [void]
257
- #
258
- # @api private
259
- def register_redis_callback(subscription, action, sucess_message = nil)
260
- subscription.callback do |subscriptions_ids|
261
- if sucess_message.present?
262
- @websocket << sucess_message.merge('subscriptions' => subscriptions_ids).to_json
263
- else
264
- log_debug "#{action} success #{sucess_message.inspect}"
265
- end
266
- end
267
- end
268
-
269
- # Register an error callback on the deferrable object and logs to file the incoming message
270
- # @see #log_debug
271
- #
272
- # @param [EM::DefaultDeferrable] subscription The subscription object
273
- # @param [string] action The action that will be checked
274
- #
275
- # @return [void]
276
- #
277
- # @api private
278
- def register_redis_error_callback(subscription, action)
279
- subscription.errback { |reply| log_debug "#{action} error #{reply.inspect}" }
280
- end
281
- end
282
- end