active_pubsub 0.0.2 → 0.0.3

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: ec487cd15cef4ce67b58a62ea1b9dc71202d0e40
4
- data.tar.gz: 641188b0b8799312a4ae42d2318ca5eb4ca36005
3
+ metadata.gz: f6d67467176a0be6bf12783385e9ccb215a61b9d
4
+ data.tar.gz: dbef4a7b649425c4d1326f982970366f1ec297ec
5
5
  SHA512:
6
- metadata.gz: eb26c9710230741ebb90fc04a2ee271492186d52d381eef9ea99e8beb28cdbc0b3ef51ccc796e94ea64911065ee9c549a1532af4aa41754c4fa05c56b6ecb621
7
- data.tar.gz: aa4cbb39249701500481b0df49177ce08dfb264a7c49f290888c1c427642705a1ab49a526e3a8f446e8cbb51a905754f9ad00a1aa785152aa8e23815f46193f2
6
+ metadata.gz: 0217c66e7d33a9acbb750c1c66617819431baf28033a5c2b373449172172ad2ceb88fe91b198a939b951e25454e9cf928079cf1b7f6d4dfc6351dcaeb966b658
7
+ data.tar.gz: d64f92f24b55f9cb09336b96b00fc98d681ac54b7c859b6a945b2632df33fc1bb3499c581b01d03533b334d709df3d656c083c9cfaa46eee62751a2065876d6d
data/README.md CHANGED
@@ -1,8 +1,104 @@
1
1
  # ActivePubsub
2
2
 
3
- TODO: Write a gem description
3
+ Service oriented observers for active record, via RabbitMQ and Bunny gem. Publish/Observe changes made to ActiveRecord models asynchronously, from different applications/services.
4
4
 
5
- ## Installation
5
+ Best examples can be found here:
6
+ https://github.com/jasonayre/active_pubsub_examples
7
+
8
+ ## Publisher Example
9
+ ``` ruby
10
+ class Post < ::ActiveRecord::Base
11
+ include ::ActivePubsub::Publishable
12
+
13
+ # This is the namespace for the local service
14
+ # The following Will set up a cms.post rabbit exchange
15
+ publish_as "cms"
16
+ end
17
+ ```
18
+
19
+ ## Subscriber example
20
+ ``` ruby
21
+ # this is an example of a service that wants to do something when posts are created,
22
+ # updated, or destroyed, in the publishing service
23
+
24
+ class PostSubscriber < ::ActivePubsub::Subscriber
25
+ observes "cms"
26
+ as "aggregator"
27
+
28
+ on :created do |record|
29
+ puts record.inspect
30
+ end
31
+
32
+ on :destroyed do |record|
33
+ puts record.inspect
34
+ end
35
+
36
+ on :updated do |record|
37
+ puts record.inspect
38
+ end
39
+ end
40
+ ```
41
+
42
+ ## Publishing events
43
+
44
+ Just include ::ActivePubsub::Publishable module into an active record class whose events you want to publish.
45
+
46
+ ``` ruby
47
+ class Post < ::ActiveRecord::Base
48
+ include ::ActivePubsub::Publishable
49
+ end
50
+ ```
51
+
52
+ Also, you need to declare a namespace to publish under, either in the main configuration or in the model
53
+
54
+ ``` ruby
55
+ class Post < ::ActiveRecord::Base
56
+ include ::ActivePubsub::Publishable
57
+ publish_as "cms"
58
+ end
59
+ ```
60
+
61
+ Or in initializer
62
+
63
+ ``` ruby
64
+ ::ActivePubsub.configure do |config|
65
+ config.publish_as = "cms"
66
+ end
67
+ ```
68
+
69
+ **IMPORTANT:** If you don't do one of the above the publisher will not be started.
70
+
71
+ The publisher simply runs in a new thread alongside your main application, connects to rabbit, and publishes the events.
72
+
73
+ ## Subscribing to Events
74
+
75
+ Subscriber runs in a separate process from your application itself. You can start the subscriber with:
76
+
77
+ ## Starting the subscriber
78
+
79
+ ```
80
+ bundle exec subscriber start
81
+ ```
82
+
83
+ ## Benchmarks/Performance
84
+
85
+ No full benchmarks, but here are the results Ive seen so far via rabbit. MacbookPro, 2.6 i7 w 16gb ram. Running one publisher app and one subscriber, via examples at https://github.com/jasonayre/active_pubsub_examples
86
+
87
+ ### Celluloid version > 0.16
88
+
89
+ I removed the gem lock to be compatibile with the most recent version of sidekiq which uses celluloid (0.15.2) or something, however I noticed a significant speed boost with > 0.16 version of celluloid.
90
+
91
+ Range of published messages/second: 250-500
92
+ Range processed (subscriber) messages/second: 250-500
93
+
94
+ ### Celluloid version 15.2
95
+
96
+ Average published messages/second: 100-150
97
+ Average processed (subscriber) messages/second: 100-150
98
+
99
+ The throughput seems to be limited by the publisher mostly, from the very limited benchmarks thus far.
100
+
101
+ ### Installation
6
102
 
7
103
  Add this line to your application's Gemfile:
8
104
 
@@ -16,9 +112,7 @@ Or install it yourself as:
16
112
 
17
113
  $ gem install active_pubsub
18
114
 
19
- ## Usage
20
115
 
21
- TODO: Write usage instructions here
22
116
 
23
117
  ## Contributing
24
118
 
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "active_attr"
22
- spec.add_dependency "celluloid-io"
22
+ spec.add_dependency "celluloid", "~> 0.15.2"
23
23
  spec.add_dependency "json"
24
24
  spec.add_dependency "bunny"
25
25
 
data/bin/subscriber CHANGED
@@ -5,18 +5,22 @@ require 'active_pubsub'
5
5
  require './config/environment.rb'
6
6
 
7
7
  class Subscriber < ::Thor
8
- desc "start", "Start Rabbit Subscriber"
8
+ desc "start", "Start ActivePubsub Subscriber"
9
9
  def start
10
- puts "Starting Rabbit Subscriber SERVER"
10
+ puts "Starting ActivePubsub Subscriber"
11
11
 
12
12
  ::ActivePubsub.load_subscribers
13
13
 
14
14
  ::ActivePubsub.start_subscribers
15
-
15
+
16
16
  puts "Subscribers Started"
17
17
  end
18
18
  end
19
19
 
20
+ #todo: write event loop that handles shutdown gracefully
21
+ #however, it seems that Bunny knows when to wake subscribers up
22
+ #so sleeping seems to be enough for now
23
+
20
24
  ::Subscriber.start
21
25
 
22
26
  sleep
data/lib/active_pubsub.rb CHANGED
@@ -56,5 +56,4 @@ require "active_pubsub/event"
56
56
  require "active_pubsub/publisher"
57
57
  require "active_pubsub/publishable"
58
58
  require "active_pubsub/subscriber"
59
-
60
59
  require 'active_pubsub/railtie' if defined?(Rails)
@@ -1,5 +1,3 @@
1
- 'celluloid/io'
2
-
3
1
  module ActivePubsub
4
2
  class Publisher
5
3
  include ::Celluloid
@@ -54,8 +52,6 @@ module ActivePubsub
54
52
 
55
53
  def publish_event(event)
56
54
  ::ActiveRecord::Base.connection_pool.with_connection do
57
- puts event.inspect
58
-
59
55
  exchanges[event.exchange].publish(serialize_event(event), :routing_key => event.routing_key)
60
56
  end
61
57
  end
@@ -4,14 +4,13 @@ module ActivePubsub
4
4
  class Railtie < ::Rails::Railtie
5
5
  # we only need publisher started if service has a publishable model
6
6
  ::ActiveSupport.on_load(:active_record) do
7
- puts "Active Record LOADED"
8
-
9
7
  if(::ActivePubsub::Publisher.publishable_model_count > 0) && !::ActivePubsub::Publisher.started?
8
+ puts "Starting Publisher"
10
9
  ::ActivePubsub::Publisher.start
11
10
  end
12
11
  end
13
12
 
14
- #todo: make redis configurable
13
+ #todo: make this do something or remove it
15
14
  def self.load_config_yml
16
15
  config_file = ::YAML.load_file(config_yml_filepath)
17
16
  return unless config_file.is_a?(Hash)
@@ -34,20 +34,21 @@ module ActivePubsub
34
34
  channel.queue(queue_for_event(event_name.to_s))
35
35
  .bind(exchange, :routing_key => routing_key_for_event(event_name))
36
36
  .subscribe do |delivery_info, properties, payload|
37
- event = deserialize_event(payload)
38
- resource = deserialize_record(event[:record])
37
+ deserialized_event = deserialize_event(payload)
38
+ deserialized_record = deserialize_record(deserialized_event[:record])
39
39
 
40
- block.call(resource)
40
+ subscriber_instance = new(deserialized_record)
41
+ subscriber_instance.instance_exec(deserialized_record, &block)
41
42
  end
42
43
  end
43
44
  end
44
45
 
45
46
  def self.deserialize_event(event)
46
- @current_event = Marshal.load(event)
47
+ @current_event = ::Marshal.load(event)
47
48
  end
48
49
 
49
50
  def self.deserialize_record(record)
50
- @current_record = Marshal.load(record)
51
+ @current_record = ::Marshal.load(record)
51
52
  end
52
53
 
53
54
  def self.observes(target_exchange)
@@ -72,5 +73,13 @@ module ActivePubsub
72
73
 
73
74
  puts message
74
75
  end
76
+
77
+ ### Instance Methods ###
78
+ attr_accessor :record
79
+
80
+ def initialize(record)
81
+ @record = record
82
+ end
83
+
75
84
  end
76
85
  end
@@ -1,3 +1,3 @@
1
1
  module ActivePubsub
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_pubsub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Ayre
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-12 00:00:00.000000000 Z
11
+ date: 2014-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_attr
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: celluloid-io
28
+ name: celluloid
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 0.15.2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 0.15.2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: json
43
43
  requirement: !ruby/object:Gem::Requirement