celluloid_pubsub 0.5.2 → 0.6.0

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.
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