ragnar 0.1.2 → 0.2.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.
@@ -3,27 +3,27 @@ require 'amqp'
3
3
  # Provide a simple connector piece that runs EM and passes through AMQP connection options
4
4
  module Ragnar
5
5
  class Connector
6
-
6
+
7
7
  class << self
8
-
8
+
9
9
  # Store the connection for later retrieval
10
10
  attr_accessor :connection
11
11
  attr_accessor :host
12
12
  attr_accessor :port
13
-
14
- @host = 'localhost'
15
- @port = '5762'
16
-
13
+
17
14
  # Pass connection options through to AMQP
18
15
  def connect
19
- @connection = AMQP.connect({host: @host, port: @port})
16
+ # backwards compatible code
17
+ host = @host.nil? ? Ragnar::Config.host : @host
18
+ port = @port.nil? ? Ragnar::Config.port : @port
19
+ @connection = AMQP.connect({:host => @host, :port => @port})
20
20
  end
21
-
21
+
22
22
  def connected?
23
23
  @connection && @connection.connected?
24
24
  end
25
-
25
+
26
26
  end
27
-
27
+
28
28
  end
29
- end
29
+ end
@@ -0,0 +1,28 @@
1
+ require 'bunny'
2
+ require 'thread'
3
+
4
+ module Ragnar
5
+ # Simple publishing via a wrapper around bunny
6
+ class SimpleQueue
7
+
8
+ def self.options
9
+ @options ||= {
10
+ :host => Ragnar::Config.host,
11
+ :port => Ragnar::Config.port,
12
+ :logging => false
13
+ }
14
+ end
15
+
16
+ # Publish to a topic exchange. Defaults to 'events'
17
+ def self.publish(message, route, exchange, exchange_type='topic')
18
+ @publish_mutex ||= ::Mutex.new
19
+
20
+ @publish_mutex.synchronize do
21
+ ::Bunny.run(options) do |bunny|
22
+ exchange = bunny.exchange(exchange, :type => exchange_type)
23
+ exchange.publish(message, :key => route)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,3 +1,3 @@
1
1
  module Ragnar
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/ragnar.rb CHANGED
@@ -1,14 +1,81 @@
1
+ require 'logger'
2
+ require 'ostruct'
1
3
  require 'ragnar/connector'
2
4
  require 'ragnar/exchange'
3
5
 
4
6
  module Ragnar
5
-
7
+
6
8
  module_function
7
-
9
+
8
10
  def exchange type, name, options={}
9
11
  x = Ragnar::Exchange.new(type, name, options)
10
12
  yield(x) if block_given?
11
13
  x
12
14
  end
13
-
14
- end
15
+
16
+ # Set all your configuration options.
17
+ # log_conf = YAML.load_file(Rails.root.join('config/gelf_logger.yml'))[Rails.env]
18
+ # Ragnar::Config.configure do |c|
19
+ # c.env = 'environment'
20
+ # c.logger = logger_instance
21
+ # c.host = 'localhost'
22
+ # c.port = 5672
23
+ # end
24
+ #
25
+ # If no logger is defined, the default will be set to Logger and output will be
26
+ # directed to STDOUT
27
+ class Config
28
+ @config = OpenStruct.new
29
+
30
+ def self.configure
31
+ yield self
32
+ end
33
+
34
+ def self.config
35
+ @config.instance_variable_get(:@table)
36
+ end
37
+
38
+ def self.valid_key?(key)
39
+ [ :logger,
40
+ :env,
41
+ :host,
42
+ :port ].include?(key)
43
+ end
44
+
45
+ def self.restore_defaults!
46
+ self.configure do |c|
47
+ c.logger = Logger.new(STDOUT)
48
+ c.env = :development
49
+ c.host = 'localhost'
50
+ c.port = 5672
51
+ end
52
+ end
53
+
54
+ def self.method_missing(sym, *args, &blk)
55
+ case
56
+ when sym.to_s =~ /(.+)=$/ && valid_key?($1.to_sym) then
57
+ @config.send(sym, *args, &blk)
58
+ when @config.respond_to?(sym) then
59
+ @config.send(sym, *args, &blk)
60
+ else
61
+ super
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ def self.log_message(level, message, params={})
68
+ ::Ragnar::Config.logger.send(level, message)
69
+ rescue => e
70
+ $stdout << <<-LOG
71
+ No Logger found in ::Ragnar::log_message
72
+
73
+ Attempted to Log:
74
+ message : #{message}
75
+ params : #{params}
76
+ LOG
77
+ $stdout << $/
78
+ end
79
+ end
80
+
81
+ Ragnar::Config.restore_defaults!
data/ragnar.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
 
22
22
  s.add_dependency 'amqp', '~>0.7.1'
23
- s.add_development_dependency 'rspec', '~>2.5.0'
23
+ s.add_dependency 'bunny'
24
+ s.add_development_dependency 'rspec'
24
25
  s.add_development_dependency 'evented-spec', '~>0.4.1'
25
26
  end
@@ -4,27 +4,39 @@ require 'ragnar/connector'
4
4
  describe Ragnar::Connector do
5
5
  include EventedSpec::SpecHelper
6
6
  include EventedSpec::AMQPSpec
7
-
7
+
8
8
  before(:each) do
9
9
  Ragnar::Connector.connection = nil
10
- Ragnar::Connector.host = 'localhost'
11
- Ragnar::Connector.port = '5762'
12
10
  end
13
-
11
+
14
12
  describe '.connect' do
15
-
16
- it 'can set host and port and have a connection' do
17
- host = 'test.md.com'
18
- port = '5763'
19
-
20
- Ragnar::Connector.host = host
21
- Ragnar::Connector.port = port
22
-
23
- AMQP.should_receive(:connect).with({host: host, port: port})
24
- Ragnar::Connector.connect
25
- done
13
+
14
+ context 'new configuration methods' do
15
+ it 'can set host and port and have a connection' do
16
+ AMQP.should_receive(:connect).with({:host => Ragnar::Config.host, :port => Ragnar::Config.port})
17
+ Ragnar::Connector.connect
18
+ done
19
+ end
20
+ end
21
+
22
+ context 'deprecated configuration methods' do
23
+ before(:each) do
24
+ Ragnar::Connector.host = 'localhost'
25
+ Ragnar::Connector.port = '5762'
26
+ end
27
+
28
+ it 'can set host and port and have a connection' do
29
+ host = 'test.md.com'
30
+ port = '5763'
31
+
32
+ Ragnar::Connector.host = host
33
+ Ragnar::Connector.port = port
34
+
35
+ AMQP.should_receive(:connect).with({host: host, port: port})
36
+ Ragnar::Connector.connect
37
+ end
26
38
  end
27
-
39
+
28
40
  it 'uses the existing reactor if it already exists' do
29
41
  em do
30
42
  EM.should_not_receive(:run)
@@ -32,11 +44,11 @@ describe Ragnar::Connector do
32
44
  done
33
45
  end
34
46
  end
35
-
47
+
36
48
  end
37
-
49
+
38
50
  describe '.connection' do
39
-
51
+
40
52
  it 'stores the connection' do
41
53
  Ragnar::Connector.connect
42
54
  delayed(0.3) {
@@ -44,15 +56,15 @@ describe Ragnar::Connector do
44
56
  done
45
57
  }
46
58
  end
47
-
59
+
48
60
  it 'does not create the connection for you' do
49
61
  AMQP.should_not_receive(:connect)
50
62
  Ragnar::Connector.connection.should be_nil
51
63
  done
52
64
  end
53
-
65
+
54
66
  end
55
-
67
+
56
68
  describe '.connected?' do
57
69
  it 'relays connection state' do
58
70
  Ragnar::Connector.connected?.should be_false
@@ -63,5 +75,5 @@ describe Ragnar::Connector do
63
75
  }
64
76
  end
65
77
  end
66
-
67
- end
78
+
79
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+ require 'ragnar'
3
+ require 'ragnar/simple_queue'
4
+
5
+ describe Ragnar::SimpleQueue do
6
+ describe '#publish' do
7
+ let(:bunny_exchange) do
8
+ m = mock
9
+ m.stub(:exchange)
10
+ m
11
+ end
12
+
13
+ let(:bunny_mock) do
14
+ bm = mock('Bunny')
15
+ bm.stub(:setup)
16
+ bm.stub(:stop)
17
+ bm.stub(:connected?)
18
+ bm.stub(:start)
19
+ bm.stub(:exchange).and_return(bunny_exchange)
20
+ bm
21
+ end
22
+
23
+ before(:each) { ::Bunny.stub(:run).and_yield(bunny_mock) }
24
+
25
+ it %{publishes a message} do
26
+ message = 'publish me'
27
+ route = 'to.the.batcave'
28
+ bunny_exchange.should_receive(:publish).with(message, {:key => route})
29
+ described_class.publish(message, route, 'event_exchange')
30
+ end
31
+
32
+ end
33
+ end
@@ -48,4 +48,76 @@ describe Ragnar do
48
48
  end
49
49
  end
50
50
 
51
- end
51
+ end
52
+
53
+ describe Ragnar::Config do
54
+ subject { Ragnar::Config }
55
+
56
+ describe '.config' do
57
+ subject { Ragnar::Config.config }
58
+ specify { subject.should include(:logger) }
59
+ specify { subject.should include(:env) }
60
+ specify { subject.should include(:host) }
61
+ specify { subject.should include(:port) }
62
+ end
63
+
64
+ describe '.valid_key?' do
65
+ # purely for --format=documentation output
66
+ matcher :return_true_for do |expected|
67
+ match {|actual| subject.valid_key?(expected) == true }
68
+ end
69
+
70
+ it { should return_true_for(:logger) }
71
+ it { should return_true_for(:env) }
72
+ it { should return_true_for(:host) }
73
+ it { should return_true_for(:port) }
74
+ it %{returns false on invalid keys} do
75
+ subject.valid_key?(:invalid_key).should be_false
76
+ end
77
+ end
78
+
79
+ describe '.restore_defaults!' do
80
+ before(:each) do
81
+ subject.configure do |c|
82
+ c.env = :untested
83
+ end
84
+ end
85
+
86
+ describe 'env' do
87
+ specify { subject.env.should eq(:untested) }
88
+ it 'changes the env back to default' do
89
+ subject.restore_defaults!
90
+ subject.env.should eq(:development)
91
+ end
92
+ end
93
+ end
94
+
95
+ describe '.method_missing' do
96
+ before(:each) { subject.restore_defaults! }
97
+ context 'when key is valid' do
98
+ it 'returns the data for that key' do
99
+ subject.env.should eq(:development)
100
+ end
101
+ end
102
+
103
+ context 'when key is not valid' do
104
+ it 'raises method missing' do
105
+ expect { subject.invalid_key }.to raise_error
106
+ end
107
+ end
108
+
109
+ context 'when key is a setter' do
110
+ it 'sets the value correctly' do
111
+ subject.env = :something_else
112
+ subject.env.should eq(:something_else)
113
+ end
114
+ end
115
+
116
+ context 'when key is a getter' do
117
+ describe 'env' do
118
+ specify { subject.env.should eq(:development) }
119
+ end
120
+ end
121
+ end
122
+ end
123
+
metadata CHANGED
@@ -1,60 +1,68 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ragnar
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
4
5
  prerelease:
5
- version: 0.1.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - BJ Neislen
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-08-15 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2012-04-17 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: amqp
17
- prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2153647520 !ruby/object:Gem::Requirement
19
17
  none: false
20
- requirements:
18
+ requirements:
21
19
  - - ~>
22
- - !ruby/object:Gem::Version
20
+ - !ruby/object:Gem::Version
23
21
  version: 0.7.1
24
22
  type: :runtime
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
27
- name: rspec
28
23
  prerelease: false
29
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *2153647520
25
+ - !ruby/object:Gem::Dependency
26
+ name: bunny
27
+ requirement: &2153647100 !ruby/object:Gem::Requirement
30
28
  none: false
31
- requirements:
32
- - - ~>
33
- - !ruby/object:Gem::Version
34
- version: 2.5.0
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2153647100
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &2153646600 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
35
44
  type: :development
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
38
- name: evented-spec
39
45
  prerelease: false
40
- requirement: &id003 !ruby/object:Gem::Requirement
46
+ version_requirements: *2153646600
47
+ - !ruby/object:Gem::Dependency
48
+ name: evented-spec
49
+ requirement: &2153646100 !ruby/object:Gem::Requirement
41
50
  none: false
42
- requirements:
51
+ requirements:
43
52
  - - ~>
44
- - !ruby/object:Gem::Version
53
+ - !ruby/object:Gem::Version
45
54
  version: 0.4.1
46
55
  type: :development
47
- version_requirements: *id003
48
- description: Provide top-level pub/sub methods with RabbitMQ (AMQP) for interacting with a larger service ecosystem
49
- email:
56
+ prerelease: false
57
+ version_requirements: *2153646100
58
+ description: Provide top-level pub/sub methods with RabbitMQ (AMQP) for interacting
59
+ with a larger service ecosystem
60
+ email:
50
61
  - bj.neilsen@gmail.com
51
62
  executables: []
52
-
53
63
  extensions: []
54
-
55
64
  extra_rdoc_files: []
56
-
57
- files:
65
+ files:
58
66
  - .gitignore
59
67
  - Gemfile
60
68
  - README.md
@@ -62,41 +70,43 @@ files:
62
70
  - lib/ragnar.rb
63
71
  - lib/ragnar/connector.rb
64
72
  - lib/ragnar/exchange.rb
73
+ - lib/ragnar/simple_queue.rb
65
74
  - lib/ragnar/version.rb
66
75
  - ragnar.gemspec
67
76
  - spec/lib/ragnar/connector_spec.rb
68
77
  - spec/lib/ragnar/exchange_spec.rb
78
+ - spec/lib/ragnar/simple_queue_spec.rb
69
79
  - spec/lib/ragnar_spec.rb
70
80
  - spec/spec_helper.rb
71
81
  homepage: http://www.rand9.com
72
82
  licenses: []
73
-
74
83
  post_install_message:
75
84
  rdoc_options: []
76
-
77
- require_paths:
85
+ require_paths:
78
86
  - lib
79
- required_ruby_version: !ruby/object:Gem::Requirement
87
+ required_ruby_version: !ruby/object:Gem::Requirement
80
88
  none: false
81
- requirements:
82
- - - ">="
83
- - !ruby/object:Gem::Version
84
- version: "0"
85
- required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
94
  none: false
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- version: "0"
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
91
99
  requirements: []
92
-
93
100
  rubyforge_project: ragnar
94
- rubygems_version: 1.8.2
101
+ rubygems_version: 1.8.15
95
102
  signing_key:
96
103
  specification_version: 3
97
- summary: Provide top-level pub/sub methods with RabbitMQ (AMQP) for interacting with a larger service ecosystem
98
- test_files:
104
+ summary: Provide top-level pub/sub methods with RabbitMQ (AMQP) for interacting with
105
+ a larger service ecosystem
106
+ test_files:
99
107
  - spec/lib/ragnar/connector_spec.rb
100
108
  - spec/lib/ragnar/exchange_spec.rb
109
+ - spec/lib/ragnar/simple_queue_spec.rb
101
110
  - spec/lib/ragnar_spec.rb
102
111
  - spec/spec_helper.rb
112
+ has_rdoc: