philotic 0.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0d1256a8211bd2888c9d9d9652fe4a6fc89de284
4
+ data.tar.gz: 20e5c1a6ffca4a788bafbc283bc3bcfbd3a868bc
5
+ SHA512:
6
+ metadata.gz: 7b7f720591f38592197ebca75e7d3cb5440d6659c87b43aa99ed04d5ce3f92c4983721f1c1ef8e91387665095a9b30f0771d6073d4b5f75d4a83d056bf032d22
7
+ data.tar.gz: ea4267f99564ad426015b55b62ccefe22365a02f1ab8a28f35f3372e28a0c53f3116a1a6f576efd38bb77eddbf07ad493d0329a16b89b9bbbc57edb7d6df270c
data/.gitignore ADDED
@@ -0,0 +1,25 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .project
19
+ philotic.yml
20
+ philotic_queues.yml
21
+ .idea/
22
+ log/*.log
23
+ .rvmrc
24
+ .ruby-version
25
+ .ruby-gemset
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format=progress
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.1.0
5
+ - 2.0.0
6
+ - jruby-19mode
7
+ - ruby-head
8
+ script:
9
+ - bundle exec rspec
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in philotic.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'pry'
8
+ gem 'rake'
9
+ gem 'rspec'
10
+ gem 'timecop'
11
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Nathan Keyes
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # Philotic
2
+
3
+ Lightweight, opinionated wrapper for using RabbitMQ headers exchanges
4
+
5
+ [![Build Status](https://travis-ci.org/nkeyes/philotic.png?branch=master)](https://travis-ci.org/nkeyes/philotic)
6
+
7
+ Check out the [examples](https://github.com/nkeyes/philotic/tree/master/examples).
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup :default, :test, :development
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ require 'rspec/core/rake_task'
8
+
9
+ require 'philotic/tasks'
10
+
11
+ RSpec::Core::RakeTask.new(:spec) do |spec|
12
+ spec.pattern = 'spec/**/*_spec.rb'
13
+ end
14
+
15
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
16
+ spec.pattern = 'spec/**/*_spec.rb'
17
+ spec.rcov = true
18
+ end
19
+
20
+ Dir["tasks/**/*.rake"].each { |ext| load ext }
21
+
22
+ task :spec
23
+ task default: :spec
24
+
@@ -0,0 +1,13 @@
1
+ # Philotic Examples
2
+ Read the code, yo!
3
+
4
+ ## (Re)Initializing Named Queues
5
+ Any project that includes Philotic can include the `philotic:init_queues[path/to/named_queues.yml]` task.
6
+
7
+ For example:
8
+ ```bash
9
+ PHILOTIC_RABBIT_HOST=localhost bundle exec rake eb:init_queues[path/to/named_queues.yml]
10
+ ```
11
+
12
+
13
+
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path( '../../../lib', __FILE__ )
3
+ $stdout.sync = true
4
+
5
+ require 'philotic'
6
+
7
+ EventMachine.run do
8
+ # hit Control + C to stop
9
+ Signal.trap("INT") { EventMachine.stop }
10
+ Signal.trap("TERM") { EventMachine.stop }
11
+
12
+ queue_after_initialize_handler = Proc.new do |q|
13
+ Philotic.logger.info "Queue '#{q.name}' initialized: #{q.bindings}"
14
+ end
15
+ # consume ansible + subspace + new_message events
16
+ ansible_arguments = {
17
+ "x-match" => :all,
18
+ philotic_product: :ansible,
19
+ philotic_component: :subspace,
20
+ philotic_event_type: :new_message,
21
+ }
22
+ Philotic.initialize_named_queue!('ansible.new_messages', ansible_arguments, &queue_after_initialize_handler)
23
+
24
+
25
+ EM.add_timer(5) { EM.stop }
26
+ end
@@ -0,0 +1,6 @@
1
+ # consume ansible + subspace + new_message events
2
+ ansible.new_messages:
3
+ - philotic_product: ansible
4
+ philotic_component: subspace
5
+ philotic_event_type: new_message
6
+ x-match: all
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path( '../../../lib', __FILE__ )
3
+ $stdout.sync = true
4
+
5
+ require 'philotic'
6
+ require 'rake'
7
+
8
+ require 'philotic/tasks'
9
+ # equivelant of:
10
+ # rake eb:init_queues[examples/creating_named_queues/philotic_named_queues.yml]
11
+ Rake::Task["eb:init_queues"].invoke(File.join(File.dirname(__FILE__),".","philotic_named_queues.yml"))
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path('../../../lib', __FILE__)
3
+ $stdout.sync = true
4
+
5
+ require 'pry'
6
+
7
+ require 'philotic'
8
+ require 'philotic/dummy_event'
9
+
10
+ EventMachine.run do
11
+ # hit Control + C to stop
12
+ #Signal.trap("INT") { EventMachine.stop }
13
+ #Signal.trap("TERM") { EventMachine.stop }
14
+
15
+
16
+ Philotic::Config.load_file(File.join(File.dirname(__FILE__), "../../", "philotic.yml"))
17
+
18
+ #Philotic::Config.message_return_handler = Proc.new { |basic_return, metadata, payload|
19
+ # p "overridden"
20
+ # Philotic.logger.warn "#{JSON.parse payload} was returned! reply_code = #{basic_return.reply_code}, reply_text = #{basic_return.reply_text}"
21
+ #}
22
+
23
+
24
+ Philotic::Connection.connect! do
25
+ def send_message number
26
+ dummy_event = Philotic::DummyEvent.new
27
+
28
+ dummy_event.philotic_firehose = true
29
+ dummy_event.philotic_product = 'rabbit'
30
+ dummy_event.philotic_component = 'speed_test'
31
+ dummy_event.philotic_event_type = 'ping'
32
+
33
+ dummy_event.subject = "Hey"
34
+ dummy_event.available = true
35
+ dummy_event.gender = [:F, :M].sample
36
+
37
+
38
+ dummy_event.message_metadata = {mandatory: true}
39
+ dummy_event.message_metadata = {app_id: 'PHX'}
40
+ dummy_event.message = "Message #{number}: Hey #{dummy_event.gender == :M ? 'dude' : 'dudette'}"
41
+ dummy_event.publish
42
+
43
+ EM.add_timer rand/10 do
44
+ send_message number + 1
45
+ end
46
+ end
47
+
48
+ send_message 1
49
+
50
+ end
51
+ end
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path('../../../lib', __FILE__)
3
+ $stdout.sync = true
4
+
5
+ require 'philotic'
6
+
7
+ EventMachine.run do
8
+ # hit Control + C to stop
9
+ # Signal.trap("INT") { EventMachine.stop }
10
+ # Signal.trap("TERM") { EventMachine.stop }
11
+
12
+ Philotic::Config.load_file(File.join(File.dirname(__FILE__), "../../", "philotic.yml"))
13
+
14
+
15
+ Philotic::Subscriber.subscribe(philotic_fire_hose: true) do |metadata, payload|
16
+ p metadata.attributes
17
+ p payload
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path('../../../lib', __FILE__)
3
+ $stdout.sync = true
4
+
5
+ require 'pry'
6
+ require 'philotic'
7
+
8
+ EventMachine.run do
9
+ # hit Control + C to stop
10
+ Signal.trap("INT") { EventMachine.stop }
11
+ Signal.trap("TERM") { EventMachine.stop }
12
+
13
+ Philotic::Config.load_file(File.join(File.dirname(__FILE__), "../../", "philotic.yml"))
14
+
15
+ # explicitly create named queues for this example
16
+ # ENV['INITIALIZE_NAMED_QUEUE'] must equal 'true' to run Philotic.initialize_named_queue!
17
+ ENV['INITIALIZE_NAMED_QUEUE'] = 'true'
18
+ Philotic.initialize_named_queue!('male_queue', :"x-match" => 'all', gender: :M, available: true) do
19
+ Philotic.initialize_named_queue!('female_queue', :"x-match" => 'all', gender: :F, available: true)
20
+ end
21
+
22
+ # give it time to actually create the queue, then subscribe
23
+ EM.add_timer(3) do
24
+ Philotic::Subscriber.subscribe('male_queue') do |metadata, payload|
25
+ p metadata.attributes
26
+ p payload
27
+ end
28
+ Philotic::Subscriber.subscribe('female_queue') do |metadata, payload|
29
+ p metadata.attributes
30
+ p payload
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path( '../../../lib', __FILE__ )
3
+ $stdout.sync = true
4
+
5
+ require 'pry'
6
+ require 'philotic'
7
+
8
+ EventMachine.run do
9
+ # hit Control + C to stop
10
+ Signal.trap("INT") { EventMachine.stop }
11
+ Signal.trap("TERM") { EventMachine.stop }
12
+
13
+ #explicitly create a named queue for this example
14
+ Philotic.initialize_named_queue!('test_queue', :"x-match" => 'any', gender: :M, available: true)
15
+
16
+ # give it time to actually create the queue, then subscribe
17
+ EM.add_timer(3) do
18
+ Philotic::Subscriber.subscribe('test_queue') do |metadata, payload|
19
+ p metadata.attributes
20
+ p payload
21
+ end
22
+ end
23
+ end
data/lib/philotic.rb ADDED
@@ -0,0 +1,144 @@
1
+ require 'awesome_print'
2
+ require 'active_support/all'
3
+
4
+ require 'pathname'
5
+
6
+ require 'logger'
7
+
8
+
9
+ module Philotic
10
+ mattr_accessor :logger
11
+ mattr_accessor :log_event_handler
12
+
13
+ CONNECTION_OPTIONS = [
14
+ :rabbit_host,
15
+ :connection_failed_handler,
16
+ :connection_loss_handler,
17
+ :timeout,
18
+ ]
19
+ EXCHANGE_OPTIONS = [
20
+ :exchange_name,
21
+ :message_return_handler,
22
+ ]
23
+ MESSAGE_OPTIONS = [
24
+ :routing_key,
25
+ :persistent,
26
+ # :immediate,
27
+ :mandatory,
28
+ :content_type,
29
+ :content_encoding,
30
+ :priority,
31
+ :message_id,
32
+ :correlation_id,
33
+ :reply_to,
34
+ :type,
35
+ :user_id,
36
+ :app_id,
37
+ :timestamp,
38
+ :expiration,
39
+ ]
40
+
41
+ PHILOTIC_HEADERS = [
42
+ :philotic_firehose,
43
+ :philotic_product,
44
+ :philotic_component,
45
+ :philotic_event_type,
46
+ ]
47
+
48
+ DEFAULT_NAMED_QUEUE_OPTIONS = {
49
+ auto_delete: false,
50
+ durable: true
51
+ }
52
+ DEFAULT_ANONYMOUS_QUEUE_OPTIONS = {
53
+ auto_delete: true,
54
+ durable: false
55
+ }
56
+
57
+ DEFAULT_SUBSCRIBE_OPTIONS = {}
58
+
59
+ def self.root
60
+ ::Pathname.new File.expand_path('../../', __FILE__)
61
+ end
62
+
63
+ def self.env
64
+ ENV['SERVICE_ENV'] || 'development'
65
+ end
66
+
67
+ def self.exchange
68
+ Philotic::Connection.exchange
69
+ end
70
+
71
+ def self.initialize_named_queue!(queue_name, config, &block)
72
+ config = config.deep_symbolize_keys
73
+
74
+
75
+ raise "ENV['INITIALIZE_NAMED_QUEUE'] must equal 'true' to run Philotic.initialize_named_queue!" unless ENV['INITIALIZE_NAMED_QUEUE'] == 'true'
76
+ connect! do
77
+ queue_options = DEFAULT_NAMED_QUEUE_OPTIONS.dup
78
+ queue_options.merge!(config[:options] || {})
79
+
80
+ AMQP.channel.queue(queue_name, queue_options) do |old_queue|
81
+ old_queue.delete do
82
+ Philotic::Connection.close do
83
+ connect! do
84
+ Philotic.logger.info "deleted old queue. queue:#{queue_name}"
85
+
86
+ bindings = Array(config[:bindings])
87
+
88
+ queue_exchange = config[:exchange] ? AMQP.channel.headers(config[:exchange], durable: true) : exchange
89
+
90
+ AMQP.channel.queue(queue_name, queue_options) do |q|
91
+ Philotic.logger.info "Created queue. queue:#{q.name}"
92
+ bindings.each_with_index do |arguments, arguments_index|
93
+ q.bind(queue_exchange, { arguments: arguments }) do
94
+ Philotic.logger.info "Added binding to queue. queue:#{q.name} binding:#{arguments}"
95
+ if arguments_index >= bindings.size - 1
96
+ Philotic.logger.info "Finished adding bindings to queue. queue:#{q.name}"
97
+ block.call(q) if block
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ def self.logger
110
+ @@logger ||= init_logger
111
+ end
112
+
113
+ def self.init_logger
114
+ Logger.new(STDOUT)
115
+ end
116
+
117
+ def self.on_publish_event(&block)
118
+ @@log_event_handler = block
119
+ end
120
+
121
+ def self.log_event_published(severity, metadata, payload, message)
122
+ if @@log_event_handler
123
+ @@log_event_handler.call(severity, metadata, payload, message)
124
+ else
125
+ logger.send(severity, "#{message}; message_metadata:#{metadata}, payload:#{payload.to_json}")
126
+ end
127
+ end
128
+
129
+ def self.connected?
130
+ Philotic::Connection.connected?
131
+ end
132
+
133
+ def self.connect! &block
134
+ Philotic::Connection.connect! &block
135
+ end
136
+ end
137
+
138
+ require 'philotic/version'
139
+ require 'philotic/connection'
140
+ require 'philotic/config'
141
+ require 'philotic/routable'
142
+ require 'philotic/event'
143
+ require 'philotic/publisher'
144
+ require 'philotic/subscriber'