promiscuous 0.7 → 0.7.1

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.
@@ -17,7 +17,7 @@ module Promiscuous
17
17
  [descriptors].flatten.each do |descriptor|
18
18
  dir, file_matcher = case descriptor
19
19
  when :publishers then # TODO Cleanup publishers
20
- when :subscribers then Promiscuous::Subscriber.subscribers.clear
20
+ when :subscribers then Promiscuous::Subscriber::AMQP.subscribers.clear
21
21
  end
22
22
  end
23
23
  end
@@ -16,7 +16,7 @@ module Promiscuous::Publisher::ClassBind
16
16
 
17
17
  def klass
18
18
  if options[:class]
19
- options[:class].to_s.constantize
19
+ "::#{options[:class]}".constantize
20
20
  else
21
21
  class_name = "::#{name.split('::').last}"
22
22
  class_name = $1 if class_name =~ /^(.+)Publisher$/
@@ -2,31 +2,17 @@ module Promiscuous::Subscriber
2
2
  autoload :ActiveRecord, 'promiscuous/subscriber/active_record'
3
3
  autoload :Mongoid, 'promiscuous/subscriber/mongoid'
4
4
  autoload :Error, 'promiscuous/subscriber/error'
5
- autoload :AMQP, 'promiscuous/subscriber/amqp'
6
5
 
7
- mattr_accessor :subscribers
8
- self.subscribers = {}
9
-
10
- def self.bind(key, subscriber)
11
- if self.subscribers.has_key?(key)
12
- raise "The subscriber '#{self.subscribers[key]}' already listen on '#{key}'"
13
- end
14
- self.subscribers[key] = subscriber
15
- end
16
-
17
- def self.get_subscriber(payload, options={})
18
- key = Promiscuous::Subscriber::AMQP.subscriber_key(payload)
19
-
20
- if key
21
- raise "FATAL: Unknown binding: '#{key}'" unless self.subscribers.has_key?(key)
22
- self.subscribers[key]
23
- else
24
- Promiscuous::Subscriber::Base
6
+ def self.get_subscriber_from(payload)
7
+ sub = AMQP.subscriber_from(payload)
8
+ if sub && defined?(Polymorphic) && sub.include?(Polymorphic)
9
+ sub = sub.polymorphic_subscriber_from(payload)
25
10
  end
11
+ sub || Base
26
12
  end
27
13
 
28
14
  def self.process(payload, options={})
29
- subscriber_klass = get_subscriber(payload)
15
+ subscriber_klass = self.get_subscriber_from(payload)
30
16
 
31
17
  sub = subscriber_klass.new(options.merge(:payload => payload))
32
18
  sub.process
@@ -3,14 +3,26 @@ require 'promiscuous/subscriber/envelope'
3
3
  module Promiscuous::Subscriber::AMQP
4
4
  extend ActiveSupport::Concern
5
5
 
6
- def self.subscriber_key(payload)
7
- payload.is_a?(Hash) ? payload['__amqp__'] : nil
6
+ mattr_accessor :subscribers
7
+ self.subscribers = {}
8
+
9
+ def self.subscriber_from(payload)
10
+ if key = payload.is_a?(Hash) ? payload['__amqp__'] : nil
11
+ unless self.subscribers.has_key?(key)
12
+ raise "Unknown binding: '#{key}'"
13
+ end
14
+ self.subscribers[key]
15
+ end
8
16
  end
9
17
 
18
+ included { use_option :from }
19
+
10
20
  module ClassMethods
11
- def subscribe(options)
21
+ def from=(value)
12
22
  super
13
- Promiscuous::Subscriber.bind(options[:from], self)
23
+ old_sub = Promiscuous::Subscriber::AMQP.subscribers[from]
24
+ raise "The subscriber '#{old_sub}' already listen on '#{from}'" if old_sub
25
+ Promiscuous::Subscriber::AMQP.subscribers[from] = self
14
26
  end
15
27
  end
16
28
  end
@@ -5,20 +5,16 @@ module Promiscuous::Subscriber::Attributes
5
5
  super
6
6
  return unless process_attributes?
7
7
 
8
- attributes.each do |attr|
8
+ self.class.attributes.each do |attr|
9
9
  attr = attr.to_s
10
- optional = attr[-1] == '?'
11
- attr = attr[0...-1] if optional
12
- setter = "#{attr}="
13
-
14
- if payload.has_key?(attr)
15
- value = payload[attr]
16
- old_value = instance.__send__(attr)
17
- new_value = Promiscuous::Subscriber.process(payload[attr], :old_value => old_value)
18
- instance.__send__(setter, new_value) if old_value != new_value
19
- else
20
- raise "Unknown attribute '#{attr}'" unless optional
10
+ unless payload.has_key?(attr)
11
+ raise "Attribute '#{attr}' is missing from the payload"
21
12
  end
13
+
14
+ value = payload[attr]
15
+ old_value = instance.__send__(attr)
16
+ new_value = Promiscuous::Subscriber.process(payload[attr], :old_value => old_value)
17
+ instance.__send__("#{attr}=", new_value) if old_value != new_value
22
18
  end
23
19
  end
24
20
 
@@ -27,4 +23,10 @@ module Promiscuous::Subscriber::Attributes
27
23
  end
28
24
 
29
25
  included { use_option :attributes }
26
+
27
+ module ClassMethods
28
+ def attributes=(value)
29
+ super(superclass.attributes.to_a + value)
30
+ end
31
+ end
30
32
  end
@@ -1,6 +1,8 @@
1
1
  class Promiscuous::Subscriber::Base
2
2
  attr_accessor :options
3
- class_attribute :options
3
+ class_attribute :options, :options_mappings, :instance_reader => false, :instance_writer => false
4
+
5
+ self.options = self.options_mappings = {}
4
6
 
5
7
  def initialize(options)
6
8
  self.options = options
@@ -19,13 +21,26 @@ class Promiscuous::Subscriber::Base
19
21
  end
20
22
 
21
23
  def self.subscribe(options)
22
- self.options = options
24
+ options.each do |attr, value|
25
+ attr_alias = self.options_mappings[attr]
26
+ self.__send__("#{attr_alias}=", value) if attr_alias
27
+ end
28
+ end
29
+
30
+ def self.inherited(subclass)
31
+ super
32
+ subclass.options = self.options.dup
23
33
  end
24
34
 
25
35
  def self.use_option(attr, options={})
26
- as = options[:as].nil? ? attr : options[:as]
27
- define_method(as) do
28
- self.class.options[attr]
36
+ attr_alias = options[:as].nil? ? attr : options[:as]
37
+ self.options_mappings[attr] = attr_alias
38
+
39
+ # We need to let all the modules overload these methods, which is
40
+ # why we are injecting at the base level.
41
+ Promiscuous::Subscriber::Base.singleton_class.class_eval do
42
+ define_method("#{attr_alias}") { self.options[attr] }
43
+ define_method("#{attr_alias}=") { |value| self.options[attr] = value }
29
44
  end
30
45
  end
31
46
  end
@@ -4,14 +4,24 @@ module Promiscuous::Subscriber::CustomClass
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  def klass
7
- unless subscribe_options[:class]
8
- raise "I don't want to be rude or anything, " +
9
- "but have you defined the class to deserialize?"
10
- end
11
- subscribe_options[:class]
7
+ self.class.klass
12
8
  end
13
9
 
14
10
  def instance
15
11
  @instance ||= fetch
16
12
  end
13
+
14
+ included { use_option :class, :as => :klass }
15
+
16
+ module ClassMethods
17
+ def klass
18
+ if super
19
+ "::#{super}".constantize
20
+ else
21
+ class_name = "::#{name.split('::').last}"
22
+ class_name = $1 if class_name =~ /^(.+)Subscriber$/
23
+ class_name.constantize
24
+ end
25
+ end
26
+ end
17
27
  end
@@ -17,10 +17,7 @@ class Promiscuous::Subscriber::Mongoid < Promiscuous::Subscriber::Base
17
17
  end
18
18
 
19
19
  def self.subscribe(options)
20
- return super if options[:mongoid_loaded]
21
-
22
- klass = options[:class]
23
- klass = options[:classes].values.first if klass.nil?
20
+ super
24
21
 
25
22
  if klass.embedded?
26
23
  require 'promiscuous/subscriber/mongoid/embedded'
@@ -32,7 +29,5 @@ class Promiscuous::Subscriber::Mongoid < Promiscuous::Subscriber::Base
32
29
  require 'promiscuous/subscriber/upsert'
33
30
  include Promiscuous::Subscriber::Upsert
34
31
  end
35
-
36
- self.subscribe(options.merge(:mongoid_loaded => true))
37
32
  end
38
33
  end
@@ -4,10 +4,41 @@ module Promiscuous::Subscriber::Polymorphic
4
4
  extend ActiveSupport::Concern
5
5
  include Promiscuous::Subscriber::Envelope
6
6
 
7
- def klass
8
- klass = (subscribe_options[:classes] || {})[type]
9
- klass.nil? ? super : klass
7
+ included do
8
+ class_attribute :polymorphic_map
9
+ use_option :from_type
10
10
  end
11
11
 
12
- included { use_payload_attribute :type }
12
+ module ClassMethods
13
+ def from_type
14
+ return super if super
15
+
16
+ if name
17
+ class_name = "#{name.split('::').last}"
18
+ class_name = $1 if class_name =~ /^(.+)Subscriber$/
19
+ class_name
20
+ end
21
+ end
22
+
23
+ def from_type=(value)
24
+ super
25
+ setup_polymorphic_mapping
26
+ end
27
+
28
+ def setup_polymorphic_mapping
29
+ self.polymorphic_map ||= {}
30
+ polymorphic_map[from_type.to_s] = self if from_type
31
+ end
32
+
33
+ def inherited(subclass)
34
+ super
35
+ subclass.setup_polymorphic_mapping unless options.has_key?(:class)
36
+ end
37
+
38
+ def polymorphic_subscriber_from(payload)
39
+ type = payload.is_a?(Hash) ? payload['type'] : nil
40
+ raise "The payload is missing the type information'" if type.nil?
41
+ polymorphic_map[type] || self
42
+ end
43
+ end
13
44
  end
@@ -1,3 +1,3 @@
1
1
  module Promiscuous
2
- VERSION = '0.7'
2
+ VERSION = '0.7.1'
3
3
  end
@@ -44,7 +44,7 @@ module Promiscuous
44
44
 
45
45
  def self.subscribe_options
46
46
  queue_name = "#{Promiscuous::Config.app}.promiscuous"
47
- bindings = Promiscuous::Subscriber.subscribers.keys
47
+ bindings = Promiscuous::Subscriber::AMQP.subscribers.keys
48
48
  {:queue_name => queue_name, :bindings => bindings}
49
49
  end
50
50
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: promiscuous
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.7'
4
+ version: 0.7.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: