celluloid_pubsub 0.9.0 → 1.0.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: c703a33e176ab7877a83eb259536afa905b9aab2
4
- data.tar.gz: d60ef25c80a4ebfffd92b9b289b9d1fdd0206a96
3
+ metadata.gz: bdde06fb1422bf75d45e6f83706c695288d9c42e
4
+ data.tar.gz: f98a1a07331fbc7fcb67ee168191c0e4510b5181
5
5
  SHA512:
6
- metadata.gz: 32e7cf4839a394666c6cc6c508781d6e2271f4faee03e4b10dc547984ea241f9fcd4e4320ee17481216f12bdaa5c4269caceac61320c770598471e5d8a28055f
7
- data.tar.gz: 086654a510e94c6a1f4ab74ff34258e95e750e54a485d3d16577643b80249833a7ee58a4db5c37e2c175a46db09025a140423b00be45fd348b307f7ca2251259
6
+ metadata.gz: 02f4c5e864fa97fa3cffbb2cdf30f0f5dddf7f6341c2b042b247cbc75209118feb79cb9570ebae48f7e7ac6928a3ebdf1df7247523001f84a0d4bf04873d25c9
7
+ data.tar.gz: b8e905df5512a160194ea0ea13e0034c62ffbaa6b05031fa63df6f7c3d2af8384b49eba3e12a2092ffefd343e28061a5823319094c754576fe086e4ccafe1ba2
data/.gitignore CHANGED
@@ -17,3 +17,4 @@ tags
17
17
  .yardoc/
18
18
  doc/
19
19
  bin/
20
+ gemfiles/*.lock
data/.reek CHANGED
@@ -7,5 +7,12 @@ TooManyMethods:
7
7
  enabled: false
8
8
  UtilityFunction:
9
9
  enabled: false
10
+ ManualDispatch:
11
+ enabled: false
12
+ InstanceVariableAssumption:
13
+ enabled: false
14
+ ClassVariable:
15
+ enabled: false
10
16
  exclude_paths:
11
- - examples
17
+ - examples/**/**
18
+ - spec/**/**
data/.rubocop.yml CHANGED
@@ -1,11 +1,16 @@
1
1
  AllCops:
2
2
  Exclude:
3
- - washout_builder.gemspec
3
+ - celluloid_pubsub.gemspec
4
4
  - bin/**/*
5
5
  - Guardfile
6
6
  - vendor/**/**
7
7
  - examples/**/**
8
+ - spec/**/*
9
+ - Gemfile
10
+ - Rakefile
8
11
 
12
+ TargetRubyVersion: 2.3
13
+
9
14
  ClassLength:
10
15
  Max: 500
11
16
 
@@ -13,9 +13,10 @@ Gem::Specification.new do |s|
13
13
 
14
14
  s.licenses = ['MIT']
15
15
  s.files = `git ls-files`.split("\n")
16
- s.test_files = s.files.grep(/^(spec)/)
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split('\n').map{ |f| File.basename(f) }
17
18
  s.require_paths = ['lib']
18
-
19
+
19
20
  s.add_runtime_dependency 'celluloid', '>= 0.16', '>= 0.16.0'
20
21
  s.add_runtime_dependency 'celluloid-io', '>= 0.16', '>= 0.16.2'
21
22
  s.add_runtime_dependency 'reel', '~> 0.6', '>= 0.6.0'
@@ -15,10 +15,10 @@ class FirstActor
15
15
 
16
16
  def on_message(message)
17
17
  if @client.succesfull_subscription?(message)
18
- puts "subscriber got successful subscription #{message.inspect}"
18
+ puts "subscriber got successful subscription #{message}"
19
19
  @client.publish('test_channel2', 'data' => ' subscriber got successfull subscription') # the message needs to be a Hash
20
20
  else
21
- puts "subscriber got message #{message.inspect}"
21
+ puts "subscriber got message #{message}"
22
22
  end
23
23
  end
24
24
 
@@ -40,10 +40,10 @@ class SecondActor
40
40
 
41
41
  def on_message(message)
42
42
  if @client.succesfull_subscription?(message)
43
- puts "publisher got successful subscription #{message.inspect}"
43
+ puts "publisher got successful subscription #{message}"
44
44
  @client.publish('test_channel', 'data' => ' my_message') # the message needs to be a Hash
45
45
  else
46
- puts "publisher got message #{message.inspect}"
46
+ puts "publisher got message #{message}"
47
47
  end
48
48
  end
49
49
 
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", ">= 4.0", ">= 4.0"
6
+ gem "celluloid", "0.16.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", ">= 4.0", ">= 4.0"
6
+ gem "celluloid", "0.17.3"
7
+
8
+ gemspec :path => "../"
data/init.rb CHANGED
@@ -1 +1,3 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
1
3
  require 'celluloid_pubsub'
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
1
3
  require 'rubygems'
2
4
  require 'bundler'
3
5
  require 'bundler/setup'
@@ -1,25 +1,44 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
1
3
  require_relative './helper'
2
4
  module CelluloidPubsub
3
5
  # base actor used for compatibility between celluloid versions
6
+ # @!attribute [r] config
7
+ # @return [Hash] The configuration classes and their aliases
4
8
  module BaseActor
5
-
6
9
  class << self
7
10
  include Helper
8
- attr_reader :config
9
11
 
12
+ # includes all the required modules in the class that includes this module
13
+ # @param [Class] base the class that will be used to include the required modules into it
14
+ # @return [void]
15
+ #
16
+ # @api public
10
17
  def included(base)
11
- base.send(:include, Celluloid)
12
- base.send(:include, Celluloid::IO)
13
- base.send(:include, CelluloidPubsub::Helper)
14
- base.send(:include, config['logger_class'])
18
+ [
19
+ Celluloid,
20
+ Celluloid::IO,
21
+ CelluloidPubsub::Helper,
22
+ config['logger_class']
23
+ ].each do |module_name|
24
+ base.send(:include, module_name)
25
+ end
15
26
  end
16
27
 
28
+ # returns the configuration classes and their aliases for celluloid
29
+ # @return [Hash] returns the configuration classes and their aliases for celluloid
30
+ #
31
+ # @api public
17
32
  def config
18
33
  {
19
34
  'logger_class' => celluloid_logger_class
20
35
  }
21
36
  end
22
37
 
38
+ # returns the logger class from celluloid depending on version
39
+ # @return [Class] returns the logger class from celluloid depending on version
40
+ #
41
+ # @api public
23
42
  def celluloid_logger_class
24
43
  if version_less_than_seventeen?
25
44
  Celluloid::Logger
@@ -28,22 +47,36 @@ module CelluloidPubsub
28
47
  end
29
48
  end
30
49
 
50
+ # returns the celluloid version loaded
51
+ # @return [String] returns the celluloid version loaded
52
+ #
53
+ # @api public
31
54
  def celluloid_version
32
55
  find_loaded_gem_property('celluloid', 'version')
33
56
  end
34
57
 
58
+ # returns true if celluloid version less than 0.17, otherwise false
59
+ # @return [Boolean] returns true if celluloid version less than 0.17, otherwise false
60
+ #
61
+ # @api public
35
62
  def version_less_than_seventeen?
36
63
  verify_gem_version(celluloid_version, '0.17', operator: '<')
37
64
  end
38
65
 
66
+ # sets up the actor supervision based on celluloid version
67
+ # @param [Class] class_name The class that will be used to supervise the actor
68
+ # @param [Hash] options Additional options needed for supervision
69
+ # @return [void]
70
+ #
71
+ # @api public
39
72
  def setup_actor_supervision(class_name, options)
73
+ actor_name, args = options.slice(:actor_name, :args).values
40
74
  if version_less_than_seventeen?
41
- class_name.supervise_as(options[:actor_name], options[:args])
75
+ class_name.supervise_as(actor_name, args)
42
76
  else
43
- class_name.supervise(as: options[:actor_name], args: [options[:args]].compact)
77
+ class_name.supervise(as: actor_name, args: [args].compact)
44
78
  end
45
79
  end
46
-
47
80
  end
48
81
  end
49
82
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
1
3
  require_relative './helper'
2
4
  module CelluloidPubsub
3
5
  # worker that subscribes to a channel or publishes to a channel
@@ -15,8 +17,18 @@ module CelluloidPubsub
15
17
  class Client
16
18
  include CelluloidPubsub::BaseActor
17
19
 
20
+ # The actor that made the connection
21
+ # @return [Celluloid::Actor] actor to which callbacks will be delegated to
22
+ attr_accessor :actor
23
+
24
+ # options that can be used to connect to webser and send additional data
25
+ # @return [Hash] the options that can be used to connect to webser and send additional data
26
+ attr_accessor :options
27
+
28
+ # The channel to which the client will subscribe to once the connection is open
29
+ # @return [String] The channel to which the client will subscribe to
30
+ attr_accessor :channel
18
31
 
19
- attr_accessor :actor, :options, :channel
20
32
  finalizer :shutdown
21
33
  # receives a list of options that are used to connect to the webserver and an actor to which the callbacks are delegated to
22
34
  # when receiving messages from a channel
@@ -88,7 +100,7 @@ module CelluloidPubsub
88
100
  #
89
101
  # @api public
90
102
  def port
91
- @port ||= @options.fetch('port', nil) || CelluloidPubsub::WebServer.find_unused_port
103
+ @port ||= @options.fetch('port', nil) || CelluloidPubsub::WebServer.find_unused_port
92
104
  end
93
105
 
94
106
  # the method will return the path of the URL on which the servers acccepts the connection
@@ -253,12 +265,7 @@ module CelluloidPubsub
253
265
  #
254
266
  # @api private
255
267
  def chat(message)
256
- final_message = nil
257
- if message.is_a?(Hash)
258
- final_message = message.to_json
259
- else
260
- final_message = JSON.dump(action: 'message', message: message)
261
- end
268
+ final_message = message.is_a?(Hash) ? message.to_json : JSON.dump(action: 'message', message: message)
262
269
  log_debug("#{@actor.class} sends JSON #{final_message}")
263
270
  connection.text final_message
264
271
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+ module CelluloidPubsub
3
+ # class used for parsing gem versions
4
+ # @!attribute [r] version
5
+ # @return [String, Integer] version that needs parsing
6
+ #
7
+ # @!attribute [r] options
8
+ # @return [Hash] The additional options for parsing the version
9
+ class GemVersionParser
10
+ attr_reader :version
11
+ attr_reader :options
12
+
13
+ # receives the version and the additional options
14
+ #
15
+ # @param [String, Integer] version the version that needs parsing
16
+ # @param [Hash] options The additional options for parsing the version
17
+ #
18
+ # @return [void]
19
+ #
20
+ # @api public
21
+ #
22
+ # :nocov:
23
+ def initialize(version, options = {})
24
+ @version = version
25
+ @options = options.is_a?(Hash) ? options : {}
26
+ end
27
+
28
+ # parses the version and returns the version with a single decimal point by default
29
+ # @return [Float]
30
+ #
31
+ # @api public
32
+ def parsed_number
33
+ return 0 if @version.blank?
34
+ @version_array = @version.to_s.split('.')
35
+ number_with_single_decimal_point if @version_array.size > 2
36
+ @version_array.join('.').to_f
37
+ end
38
+
39
+ # pops from the version array elements until its size is 2
40
+ # @return [void]
41
+ #
42
+ # @api public
43
+ def number_with_single_decimal_point
44
+ @version_array.pop until @version_array.size == 2
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,6 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require_relative './gem_version_parser'
1
4
  module CelluloidPubsub
2
5
  # class that holds the options that are configurable for this gem
3
6
  module Helper
@@ -12,31 +15,61 @@ module CelluloidPubsub
12
15
  message.is_a?(Hash) && message['client_action'] == 'successful_subscription'
13
16
  end
14
17
 
15
- module_function
18
+ module_function
16
19
 
20
+ # returns the gem's property from its speification or nil
21
+ # @param [String] name the name of the gem
22
+ # @param [String] property name of the property we want
23
+ #
24
+ # @return [String, nil] returns the version of the gem
25
+ #
26
+ # @api public
17
27
  def find_loaded_gem(name, property = nil)
18
28
  gem_spec = Gem.loaded_specs.values.find { |repo| repo.name == name }
19
29
  gem_spec.present? && property.present? ? gem_spec.send(property) : gem_spec
20
30
  end
21
31
 
32
+ # returns the gem's property from its speification or nil
33
+ # @param [String] gem_name name of the gem
34
+ # @param [String] property name of the property we want
35
+ #
36
+ # @return [String, nil] returns the version of the gem
37
+ #
38
+ # @api public
22
39
  def find_loaded_gem_property(gem_name, property = 'version')
23
40
  find_loaded_gem(gem_name, property)
24
41
  end
25
42
 
43
+ # returns the parsed version of the gem
44
+ # @param [String] gem_name name of the gem
45
+ #
46
+ # @return [Float, nil] returns the version of the gem
47
+ #
48
+ # @api public
26
49
  def fetch_gem_version(gem_name)
27
50
  version = find_loaded_gem_property(gem_name)
28
51
  version.blank? ? nil : get_parsed_version(version)
29
52
  end
30
53
 
54
+ # returns the parsed version as a float or nil
55
+ # @param [String] version the version that needs to be parsed
56
+ #
57
+ # @return [Float, nil] returns the version of the gem
58
+ #
59
+ # @api public
31
60
  def get_parsed_version(version)
32
- return 0 if version.blank?
33
- version = version.to_s.split('.')
34
- if version.size > 2
35
- version.pop until version.size == 2
36
- end
37
- version.join('.').to_f
61
+ version_parser = CelluloidPubsub::GemVersionParser.new(version)
62
+ version_parser.parsed_number
38
63
  end
39
64
 
65
+ # returns true if gem_version is less or equal to the specified version, otherwise false
66
+ # @param [String] gem_version the version of the gem
67
+ # @param [String] version the version that will be checked against
68
+ # @param [Hash] options additional options
69
+ #
70
+ # @return [Boolean] returns true if gem_version is less or equal to the specified version, otherwise false
71
+ #
72
+ # @api public
40
73
  def verify_gem_version(gem_version, version, options = {})
41
74
  options.stringify_keys!
42
75
  version = get_parsed_version(version)
@@ -1,8 +1,10 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
1
3
  require 'reel/spy'
2
4
  Reel::Spy::Colors.class_eval do
3
5
  alias_method :original_colorize, :colorize
4
6
 
5
- def colorize(n, str)
7
+ def colorize(_n, str)
6
8
  force_utf8_encoding(str)
7
9
  end
8
10
 
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
1
3
  require_relative './registry'
2
4
  require_relative './helper'
3
5
  module CelluloidPubsub
@@ -15,7 +17,21 @@ module CelluloidPubsub
15
17
  class Reactor
16
18
  include CelluloidPubsub::BaseActor
17
19
 
18
- attr_accessor :websocket, :server, :channels
20
+ # available actions that can be delegated
21
+ AVAILABLE_ACTIONS = %w(unsubscribe_clients unsubscribe subscribe publish unsubscribe_all).freeze
22
+
23
+ # The websocket connection received from the server
24
+ # @return [Reel::WebSocket] websocket connection
25
+ attr_accessor :websocket
26
+
27
+ # The server instance to which this reactor is linked to
28
+ # @return [CelluloidPubsub::Webserver] the server actor to which the reactor is connected to
29
+ attr_accessor :server
30
+
31
+ # The channels to which this reactor has subscribed to
32
+ # @return [Array] array of channels to which the current reactor has subscribed to
33
+ attr_accessor :channels
34
+
19
35
  finalizer :shutdown
20
36
  # rececives a new socket connection from the server
21
37
  # and listens for messages
@@ -163,21 +179,9 @@ module CelluloidPubsub
163
179
  #
164
180
  # @api public
165
181
  def delegate_action(json_data)
166
- channel = json_data.fetch('channel', nil)
167
- case json_data['client_action']
168
- when 'unsubscribe_all'
169
- unsubscribe_all
170
- when 'unsubscribe_clients'
171
- async.unsubscribe_clients(channel)
172
- when 'unsubscribe'
173
- async.unsubscribe(channel)
174
- when 'subscribe'
175
- async.start_subscriber(channel, json_data)
176
- when 'publish'
177
- async.publish_event(channel, json_data['data'].to_json)
178
- else
179
- handle_unknown_action(json_data)
180
- end
182
+ channel, client_action = json_data.slice('channel', 'client_action').values
183
+ return unless CelluloidPubsub::Reactor::AVAILABLE_ACTIONS.include?(client_action)
184
+ async.send(client_action, channel, json_data)
181
185
  end
182
186
 
183
187
  # the method will delegate the message to the server in an asyncronous way by sending the current actor and the message
@@ -188,8 +192,8 @@ module CelluloidPubsub
188
192
  # @return [void]
189
193
  #
190
194
  # @api public
191
- def handle_unknown_action(json_data)
192
- log_debug "Trying to dispatch to server #{json_data}"
195
+ def handle_unknown_action(channel, json_data)
196
+ log_debug "Trying to dispatch to server #{json_data} on channel #{channel}"
193
197
  @server.async.handle_dispatched_message(Actor.current, json_data)
194
198
  end
195
199
 
@@ -217,10 +221,21 @@ module CelluloidPubsub
217
221
  # @return [void]
218
222
  #
219
223
  # @api public
220
- def unsubscribe(channel)
224
+ def unsubscribe(channel, _json_data)
221
225
  log_debug "#{self.class} runs 'unsubscribe' method with #{channel}"
222
226
  return unless channel.present?
223
227
  forget_channel(channel)
228
+ delete_server_subscribers(channel)
229
+ end
230
+
231
+ # the method will delete the reactor from the channel list on the server
232
+ #
233
+ # @param [String] channel
234
+ #
235
+ # @return [void]
236
+ #
237
+ # @api public
238
+ def delete_server_subscribers(channel)
224
239
  @server.mutex.synchronize do
225
240
  (@server.subscribers[channel] || []).delete_if do |hash|
226
241
  hash[:reactor] == Actor.current
@@ -235,7 +250,7 @@ module CelluloidPubsub
235
250
  # @return [void]
236
251
  #
237
252
  # @api public
238
- def unsubscribe_clients(channel)
253
+ def unsubscribe_clients(channel, _json_data)
239
254
  log_debug "#{self.class} runs 'unsubscribe_clients' method with #{channel}"
240
255
  return if channel.blank?
241
256
  unsubscribe_from_channel(channel)
@@ -265,7 +280,7 @@ module CelluloidPubsub
265
280
  # @return [void]
266
281
  #
267
282
  # @api public
268
- def start_subscriber(channel, message)
283
+ def subscribe(channel, message)
269
284
  return unless channel.present?
270
285
  add_subscriber_to_channel(channel, message)
271
286
  log_debug "#{self.class} subscribed to #{channel} with #{message}"
@@ -305,28 +320,44 @@ module CelluloidPubsub
305
320
  # method for publishing data to a channel
306
321
  #
307
322
  # @param [String] current_topic The Channel to which the reactor instance {CelluloidPubsub::Reactor} will publish the message to
308
- # @param [Object] message
323
+ # @param [Object] json_data The additional data that contains the message that needs to be sent
309
324
  #
310
325
  # @return [void]
311
326
  #
312
327
  # @api public
313
- def publish_event(current_topic, message)
328
+ def publish(current_topic, json_data)
329
+ message = json_data['data'].to_json
314
330
  return if current_topic.blank? || message.blank?
331
+ server_pusblish_event(current_topic, message)
332
+ rescue => exception
333
+ log_debug("could not publish message #{message} into topic #{current_topic} because of #{exception.inspect}")
334
+ end
335
+
336
+ # the method will publish to all subsribers of a channel a message
337
+ #
338
+ # @param [String] current_topic
339
+ # @param [#to_s] message
340
+ #
341
+ # @return [void]
342
+ #
343
+ # @api public
344
+ def server_pusblish_event(current_topic, message)
315
345
  @server.mutex.synchronize do
316
346
  (@server.subscribers[current_topic].dup || []).pmap do |hash|
317
347
  hash[:reactor].websocket << message
318
348
  end
319
349
  end
320
- rescue => exception
321
- log_debug("could not publish message #{message} into topic #{current_topic} because of #{exception.inspect}")
322
350
  end
323
351
 
324
352
  # unsubscribes all actors from all channels and terminates the curent actor
325
353
  #
354
+ # @param [String] _channel NOT USED - needed to maintain compatibility with the other methods
355
+ # @param [Object] _json_data NOT USED - needed to maintain compatibility with the other methods
356
+ #
326
357
  # @return [void]
327
358
  #
328
359
  # @api public
329
- def unsubscribe_all
360
+ def unsubscribe_all(_channel, _json_data)
330
361
  log_debug "#{self.class} runs 'unsubscribe_all' method"
331
362
  CelluloidPubsub::Registry.channels.dup.pmap do |channel|
332
363
  unsubscribe_clients(channel)
@@ -343,6 +374,16 @@ module CelluloidPubsub
343
374
  # @api public
344
375
  def unsubscribe_from_channel(channel)
345
376
  log_debug "#{self.class} runs 'unsubscribe_from_channel' method with #{channel}"
377
+ server_kill_reactors(channel)
378
+ end
379
+
380
+ # kills all reactors registered on a channel and closes their websocket connection
381
+ #
382
+ # @param [String] channel
383
+ # @return [void]
384
+ #
385
+ # @api public
386
+ def server_kill_reactors(channel)
346
387
  @server.mutex.synchronize do
347
388
  (@server.subscribers[channel].dup || []).pmap do |hash|
348
389
  reactor = hash[:reactor]
@@ -1,9 +1,13 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
1
3
  module CelluloidPubsub
2
4
  # class used to register new channels and save them in memory
5
+ # @attr channels
6
+ # @return [Array] array of channels to which actors have subscribed to
3
7
  class Registry
4
8
  class << self
5
- # @!attribute channels
6
- # @return [Array] array of channels to which actors have subscribed to
9
+ # The channels that the server can handle
10
+ # @return [Array] array of channels to which actors have subscribed to
7
11
  attr_accessor :channels
8
12
  end
9
13
  @channels = []
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
1
3
  # Returns the version of the gem as a <tt>Gem::Version</tt>
2
4
  module CelluloidPubsub
3
5
  # it prints the gem version as a string
@@ -13,14 +15,14 @@ module CelluloidPubsub
13
15
  # provides a easy way of getting the major, minor and tiny
14
16
  module VERSION
15
17
  # major release version
16
- MAJOR = 0
18
+ MAJOR = 1
17
19
  # minor release version
18
- MINOR = 9
20
+ MINOR = 0
19
21
  # tiny release version
20
22
  TINY = 0
21
23
  # prelease version ( set this only if it is a prelease)
22
24
  PRE = nil
23
-
25
+
24
26
  # generates the version string
25
27
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
26
28
  end
@@ -1,18 +1,22 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
1
3
  require_relative './reactor'
2
4
  require_relative './helper'
3
5
  module CelluloidPubsub
4
6
  # webserver to which socket connects should connect to .
5
7
  # the server will dispatch each request into a new Reactor
6
8
  # which will handle the action based on the message
7
- # @!attribute options
9
+ # @attr server_options
8
10
  # @return [Hash] options used to configure the webserver
9
- # @option options [String]:hostname The hostname on which the webserver runs on
10
- # @option options [Integer] :port The port on which the webserver runs on
11
- # @option options [String] :path The request path that the webserver accepts
12
- # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
11
+ # @option server_options [String]:hostname The hostname on which the webserver runs on
12
+ # @option server_options [Integer] :port The port on which the webserver runs on
13
+ # @option server_options [String] :path The request path that the webserver accepts
14
+ # @option server_options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
13
15
  #
14
- # @!attribute subscribers
16
+ # @attr subscribers
15
17
  # @return [Hash] The hostname on which the webserver runs on
18
+ # @attr mutex
19
+ # @return [Mutex] The mutex that will synchronize actions on subscribers
16
20
  class WebServer < Reel::Server::HTTP
17
21
  include CelluloidPubsub::BaseActor
18
22
 
@@ -20,7 +24,7 @@ module CelluloidPubsub
20
24
  HOST = '0.0.0.0'
21
25
  # The request path that the webserver accepts by default
22
26
  PATH = '/ws'
23
- # The name of the default adapter
27
+ # The name of the default adapter
24
28
  CLASSIC_ADAPTER = 'classic'
25
29
 
26
30
  attr_accessor :server_options, :subscribers, :mutex
@@ -55,12 +59,30 @@ module CelluloidPubsub
55
59
  #
56
60
  # @api public
57
61
  def self.open_socket_on_unused_port
58
- infos = ::Socket::getaddrinfo("localhost", nil, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)
59
- families = Hash[*infos.collect { |af, *_| af }.uniq.zip([]).flatten]
62
+ return ::TCPServer.open('0.0.0.0', 0) if socket_families.key?('AF_INET')
63
+ return ::TCPServer.open('::', 0) if socket_families.key?('AF_INET6')
64
+ ::TCPServer.open(0)
65
+ end
60
66
 
61
- return ::TCPServer.open('0.0.0.0', 0) if families.has_key?('AF_INET')
62
- return ::TCPServer.open('::', 0) if families.has_key?('AF_INET6')
63
- return ::TCPServer.open(0)
67
+ # the method will return the socket information available as an array
68
+ #
69
+ #
70
+ # @return [Array] return the socket information available as an array
71
+ #
72
+ # @api public
73
+ def self.socket_infos
74
+ ::Socket::getaddrinfo('localhost', nil, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)
75
+ end
76
+
77
+ # the method will return the socket families avaiable
78
+ #
79
+ #
80
+ # @return [Hash] return the socket families available as keys in the hash
81
+ #
82
+ # @api public
83
+ # rubocop:disable ClassVars
84
+ def self.socket_families
85
+ @@socket_families ||= Hash[*socket_infos.map { |af, *_| af }.uniq.zip([]).flatten]
64
86
  end
65
87
 
66
88
  # the method get from the socket connection that is already opened the port used.
@@ -77,6 +99,7 @@ module CelluloidPubsub
77
99
  port
78
100
  end
79
101
  end
102
+ # rubocop:enable ClassVars
80
103
 
81
104
  # this method is overriden from the Reel::Server::HTTP in order to set the spy to the celluloid logger
82
105
  # before the connection is accepted.
@@ -105,7 +128,7 @@ module CelluloidPubsub
105
128
  #
106
129
  # @api public
107
130
  def debug_enabled?
108
- @debug_enabled = @server_options.fetch('enable_debug', false)
131
+ @debug_enabled = @server_options.fetch('enable_debug', true)
109
132
  @debug_enabled == true
110
133
  end
111
134
 
@@ -180,7 +203,6 @@ module CelluloidPubsub
180
203
  @backlog = @server_options.fetch('backlog', 1024)
181
204
  end
182
205
 
183
-
184
206
  # callback that will execute when receiving new conections
185
207
  # If the connections is a websocket will call method {#route_websocket}
186
208
  # and if the connection is HTTP will call method {#route_request}
@@ -263,13 +285,13 @@ module CelluloidPubsub
263
285
  #
264
286
  # @api public
265
287
  def route_websocket(reactor, socket)
266
- url = socket.url
267
- if url == path || url == "/?"
288
+ url = socket.url
289
+ if url == path || url == '/?'
268
290
  reactor.async.work(socket, Actor.current)
269
- else
270
- log_debug "Received invalid WebSocket request for: #{url}"
271
- socket.close
272
- end
291
+ else
292
+ log_debug "Received invalid WebSocket request for: #{url}"
293
+ socket.close
294
+ end
273
295
  end
274
296
 
275
297
  # If the message can be parsed into a Hash it will respond to the reactor's websocket connection with the same message in JSON format
@@ -284,11 +306,7 @@ module CelluloidPubsub
284
306
  def handle_dispatched_message(reactor, data)
285
307
  log_debug "#{self.class} trying to dispatch message #{data.inspect}"
286
308
  message = reactor.parse_json_data(data)
287
- if message.present? && message.is_a?(Hash)
288
- final_data = message.to_json
289
- else
290
- final_data = data.to_json
291
- end
309
+ final_data = message.present? && message.is_a?(Hash) ? message.to_json : data.to_json
292
310
  reactor.websocket << final_data
293
311
  end
294
312
  end
data/spec/spec_helper.rb CHANGED
@@ -50,7 +50,7 @@ end
50
50
  class TestActor
51
51
  include CelluloidPubsub::BaseActor
52
52
 
53
- def initialize(*args)
53
+ def initialize(*_args)
54
54
  end
55
55
  end
56
56
 
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.9.0
4
+ version: 1.0.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-07-25 00:00:00.000000000 Z
11
+ date: 2016-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid
@@ -361,10 +361,13 @@ files:
361
361
  - Rakefile
362
362
  - celluloid_pubsub.gemspec
363
363
  - examples/simple_test.rb
364
+ - gemfiles/celluloid_0.16.0.gemfile
365
+ - gemfiles/celluloid_0.17.3.gemfile
364
366
  - init.rb
365
367
  - lib/celluloid_pubsub.rb
366
368
  - lib/celluloid_pubsub/base_actor.rb
367
369
  - lib/celluloid_pubsub/client.rb
370
+ - lib/celluloid_pubsub/gem_version_parser.rb
368
371
  - lib/celluloid_pubsub/helper.rb
369
372
  - lib/celluloid_pubsub/initializers/reel_colors.rb
370
373
  - lib/celluloid_pubsub/reactor.rb
@@ -401,10 +404,5 @@ signing_key:
401
404
  specification_version: 4
402
405
  summary: CelluloidPubsub is a simple ruby implementation of publish subscribe design
403
406
  patterns using celluloid actors and websockets, using Celluloid::Reel server
404
- test_files:
405
- - spec/lib/celluloid_pubsub/client_pubsub_spec.rb
406
- - spec/lib/celluloid_pubsub/reactor_spec.rb
407
- - spec/lib/celluloid_pubsub/registry_spec.rb
408
- - spec/lib/celluloid_pubsub/web_server_spec.rb
409
- - spec/spec_helper.rb
407
+ test_files: []
410
408
  has_rdoc: