promiscuous 0.7 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: