ragnar 0.1.2 → 0.2.0

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