a13g 0.1.0.beta3 → 0.1.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/Rakefile +53 -0
- data/a13g-0.1.0.beta3.gem +0 -0
- data/a13g.gemspec +100 -0
- data/examples/consumer.rb +16 -0
- data/examples/multiple_connections.rb +26 -0
- data/examples/producer.rb +11 -0
- data/examples/simple_project/README +3 -0
- data/examples/simple_project/Rakefile +6 -0
- data/examples/simple_project/config/broker.yml +10 -0
- data/examples/simple_project/lib/consumers/first_consumer.rb +7 -0
- data/examples/simple_project/lib/consumers/second_consumer.rb +9 -0
- data/examples/simple_project/lib/simple_project.rb +20 -0
- data/lib/a13g.rb +68 -0
- data/lib/a13g/adapters.rb +45 -0
- data/lib/a13g/adapters/abstract_adapter.rb +330 -0
- data/lib/a13g/adapters/stomp_adapter.rb +163 -0
- data/lib/a13g/adapters/test_adapter.rb +102 -0
- data/lib/a13g/base.rb +448 -0
- data/lib/a13g/command.rb +69 -0
- data/lib/a13g/consumer.rb +129 -0
- data/lib/a13g/destination.rb +22 -0
- data/lib/a13g/errors.rb +60 -0
- data/lib/a13g/listener.rb +190 -0
- data/lib/a13g/message.rb +68 -0
- data/lib/a13g/producer.rb +107 -0
- data/lib/a13g/railtie.rb +4 -0
- data/lib/a13g/recipes.rb +31 -0
- data/lib/a13g/subscription.rb +123 -0
- data/lib/a13g/support/logger.rb +194 -0
- data/lib/a13g/support/utils.rb +25 -0
- data/lib/a13g/utils.rb +25 -0
- data/lib/a13g/version.rb +10 -0
- data/spec/a13g_spec.rb +74 -0
- data/spec/config/broker.yml +4 -0
- data/spec/dconfig/broker.yml +4 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +14 -0
- metadata +50 -4
data/.document
ADDED
data/.gitignore
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), 'lib/a13g/version')
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
gem.name = "a13g"
|
10
|
+
gem.version = A13g::VERSION::STRING
|
11
|
+
gem.summary = "Event-driven architecture for your applications"
|
12
|
+
gem.description = <<-DESCR
|
13
|
+
A13g allows you to use event-driven architecture in your applications It can be
|
14
|
+
used for enterprise integration with frameworks like JMS and products
|
15
|
+
such as ActiveMQ.
|
16
|
+
DESCR
|
17
|
+
gem.email = "kriss.kowalik@gmail.com"
|
18
|
+
gem.homepage = "http://github.com/kriss/a13g"
|
19
|
+
gem.authors = ["Kriss Kowalik"]
|
20
|
+
gem.add_dependency "activesupport", ">= 2.0.0"
|
21
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
22
|
+
gem.add_development_dependency "yard", ">= 0"
|
23
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
24
|
+
end
|
25
|
+
Jeweler::GemcutterTasks.new
|
26
|
+
rescue LoadError
|
27
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'spec/rake/spectask'
|
31
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
32
|
+
spec.libs << 'lib' << 'spec'
|
33
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
34
|
+
end
|
35
|
+
|
36
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
37
|
+
spec.libs << 'lib' << 'spec'
|
38
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
39
|
+
spec.rcov = true
|
40
|
+
end
|
41
|
+
|
42
|
+
task :spec => :check_dependencies
|
43
|
+
|
44
|
+
task :default => :spec
|
45
|
+
|
46
|
+
begin
|
47
|
+
require 'yard'
|
48
|
+
YARD::Rake::YardocTask.new
|
49
|
+
rescue LoadError
|
50
|
+
task :yardoc do
|
51
|
+
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
52
|
+
end
|
53
|
+
end
|
Binary file
|
data/a13g.gemspec
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{a13g}
|
8
|
+
s.version = "0.1.0.beta4"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Kriss Kowalik"]
|
12
|
+
s.date = %q{2010-07-26}
|
13
|
+
s.description = %q{A13g allows you to use event-driven architecture in your applications It can be
|
14
|
+
used for enterprise integration with frameworks like JMS and products
|
15
|
+
such as ActiveMQ.
|
16
|
+
}
|
17
|
+
s.email = %q{kriss.kowalik@gmail.com}
|
18
|
+
s.extra_rdoc_files = [
|
19
|
+
"LICENSE",
|
20
|
+
"README.rdoc"
|
21
|
+
]
|
22
|
+
s.files = [
|
23
|
+
".document",
|
24
|
+
".gitignore",
|
25
|
+
"LICENSE",
|
26
|
+
"README.rdoc",
|
27
|
+
"Rakefile",
|
28
|
+
"a13g-0.1.0.beta3.gem",
|
29
|
+
"a13g.gemspec",
|
30
|
+
"examples/consumer.rb",
|
31
|
+
"examples/multiple_connections.rb",
|
32
|
+
"examples/producer.rb",
|
33
|
+
"examples/simple_project/README",
|
34
|
+
"examples/simple_project/Rakefile",
|
35
|
+
"examples/simple_project/config/broker.yml",
|
36
|
+
"examples/simple_project/lib/consumers/first_consumer.rb",
|
37
|
+
"examples/simple_project/lib/consumers/second_consumer.rb",
|
38
|
+
"examples/simple_project/lib/simple_project.rb",
|
39
|
+
"lib/a13g.rb",
|
40
|
+
"lib/a13g/adapters.rb",
|
41
|
+
"lib/a13g/adapters/abstract_adapter.rb",
|
42
|
+
"lib/a13g/adapters/stomp_adapter.rb",
|
43
|
+
"lib/a13g/adapters/test_adapter.rb",
|
44
|
+
"lib/a13g/base.rb",
|
45
|
+
"lib/a13g/command.rb",
|
46
|
+
"lib/a13g/consumer.rb",
|
47
|
+
"lib/a13g/destination.rb",
|
48
|
+
"lib/a13g/errors.rb",
|
49
|
+
"lib/a13g/listener.rb",
|
50
|
+
"lib/a13g/message.rb",
|
51
|
+
"lib/a13g/producer.rb",
|
52
|
+
"lib/a13g/railtie.rb",
|
53
|
+
"lib/a13g/recipes.rb",
|
54
|
+
"lib/a13g/subscription.rb",
|
55
|
+
"lib/a13g/support/logger.rb",
|
56
|
+
"lib/a13g/support/utils.rb",
|
57
|
+
"lib/a13g/utils.rb",
|
58
|
+
"lib/a13g/version.rb",
|
59
|
+
"spec/a13g_spec.rb",
|
60
|
+
"spec/config/broker.yml",
|
61
|
+
"spec/dconfig/broker.yml",
|
62
|
+
"spec/spec.opts",
|
63
|
+
"spec/spec_helper.rb"
|
64
|
+
]
|
65
|
+
s.homepage = %q{http://github.com/kriss/a13g}
|
66
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
67
|
+
s.require_paths = ["lib"]
|
68
|
+
s.rubygems_version = %q{1.3.6}
|
69
|
+
s.summary = %q{Event-driven architecture for your applications}
|
70
|
+
s.test_files = [
|
71
|
+
"spec/a13g_spec.rb",
|
72
|
+
"spec/spec_helper.rb",
|
73
|
+
"examples/consumer.rb",
|
74
|
+
"examples/multiple_connections.rb",
|
75
|
+
"examples/simple_project/lib/consumers/second_consumer.rb",
|
76
|
+
"examples/simple_project/lib/consumers/first_consumer.rb",
|
77
|
+
"examples/simple_project/lib/simple_project.rb",
|
78
|
+
"examples/producer.rb"
|
79
|
+
]
|
80
|
+
|
81
|
+
if s.respond_to? :specification_version then
|
82
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
83
|
+
s.specification_version = 3
|
84
|
+
|
85
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
86
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.0.0"])
|
87
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
88
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
89
|
+
else
|
90
|
+
s.add_dependency(%q<activesupport>, [">= 2.0.0"])
|
91
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
92
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
93
|
+
end
|
94
|
+
else
|
95
|
+
s.add_dependency(%q<activesupport>, [">= 2.0.0"])
|
96
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
97
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
#require 'a13g'
|
3
|
+
require File.dirname(__FILE__)+'/../lib/a13g'
|
4
|
+
|
5
|
+
A13g.setup(:default, :adapter => 'stomp') # localhost:61613
|
6
|
+
|
7
|
+
class MyConsumer < A13g::Consumer
|
8
|
+
subscribe "/queue/Example", :ack => :client
|
9
|
+
|
10
|
+
def on_message(message)
|
11
|
+
puts message.body
|
12
|
+
message.ack!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
A13g.listen!
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
#require 'a13g'
|
3
|
+
require File.dirname(__FILE__)+'/../lib/a13g'
|
4
|
+
|
5
|
+
A13g.setup(:default, :adapter => 'stomp', :host => 'first.example.com')
|
6
|
+
A13g.setup(:second, :adapter => 'stomp', :host => 'second.example.com')
|
7
|
+
|
8
|
+
class FirstConsumer < A13g::Consumer
|
9
|
+
subscribe "/queue/First"
|
10
|
+
|
11
|
+
def on_message(message)
|
12
|
+
# will send message using `:second` connection.
|
13
|
+
publish "/queue/Second", message.body, {}, :second
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class SecondConsumer < A13g::Consumer
|
18
|
+
context :second
|
19
|
+
subscribe "/queue/Second"
|
20
|
+
|
21
|
+
def on_message(message)
|
22
|
+
puts message.body
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
A13g.listen!
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
#require 'a13g'
|
3
|
+
require File.dirname(__FILE__)+'/../lib/a13g'
|
4
|
+
|
5
|
+
A13g.setup(:default, :adapter => 'stomp') # localhost:61613
|
6
|
+
|
7
|
+
include A13g::Producer
|
8
|
+
|
9
|
+
publish "/queue/Example", "My first message"
|
10
|
+
publish "/topic/Example", "My second message..."
|
11
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
#require 'a13g'
|
3
|
+
require File.dirname(__FILE__)+'/../../../../lib/a13g'
|
4
|
+
|
5
|
+
ROOT_PATH = File.dirname(__FILE__)
|
6
|
+
|
7
|
+
# By default directories structure is fit to rails application, that is:
|
8
|
+
#
|
9
|
+
# log: ROOT_PATH/log/messaging.log
|
10
|
+
# config: ROOT_PATH/config/broker.yml
|
11
|
+
# consumers: ROOT_PATH/app/consumers/
|
12
|
+
#
|
13
|
+
A13g.path.log = '/var/log/a13g_example.log'
|
14
|
+
A13g.path.config = File.join(ROOT_PATH, '../config/broker.yml')
|
15
|
+
A13g.path.consumers = File.join(ROOT_PATH, 'consumers')
|
16
|
+
|
17
|
+
A13g.setup(:default)
|
18
|
+
A13g.setup(:second, :adapter => 'stomp', :host => 'localhost')
|
19
|
+
|
20
|
+
A13g.listen!
|
data/lib/a13g.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
unless defined?(ActiveSupport)
|
4
|
+
require 'active_support'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'a13g/version'
|
8
|
+
require 'a13g/errors'
|
9
|
+
|
10
|
+
module A13g
|
11
|
+
autoload :Base, 'a13g/base'
|
12
|
+
autoload :Producer, 'a13g/producer'
|
13
|
+
autoload :Message, 'a13g/message'
|
14
|
+
autoload :Destination, 'a13g/destination'
|
15
|
+
autoload :Utils, 'a13g/support/utils'
|
16
|
+
autoload :Consumer, 'a13g/consumer'
|
17
|
+
autoload :Producer, 'a13g/producer'
|
18
|
+
autoload :Subscription, 'a13g/subscription'
|
19
|
+
autoload :Listener, 'a13g/listener'
|
20
|
+
autoload :Logger, 'a13g/support/logger'
|
21
|
+
autoload :Adapters, 'a13g/adapters'
|
22
|
+
autoload :AbstractAdapter, "a13g/adapters/abstract_adapter"
|
23
|
+
|
24
|
+
autoload :MessagingError, 'a13g/errors'
|
25
|
+
autoload :MissingDefaultContext, 'a13g/errors'
|
26
|
+
autoload :ConnectionNotEstablished, 'a13g/errors'
|
27
|
+
autoload :NoDestinationError, 'a13g/errors'
|
28
|
+
autoload :AdapterNotSpecified, 'a13g/errors'
|
29
|
+
autoload :AdapterNotFound, 'a13g/errors'
|
30
|
+
autoload :ConfigurationFileNotFound, 'a13g/errors'
|
31
|
+
autoload :StopProcessing, 'a13g/errors'
|
32
|
+
autoload :AbortMessage, 'a13g/errors'
|
33
|
+
autoload :IgnoreMessage, 'a13g/errors'
|
34
|
+
autoload :DestinationAlreadyDefined, 'a13g/errors'
|
35
|
+
autoload :DestinationNotDefinedError, 'a13g/errors'
|
36
|
+
autoload :DestinationAlreadySubscribedError, 'a13g/errors'
|
37
|
+
autoload :TooManySubscriptionsError, 'a13g/errors'
|
38
|
+
autoload :ContextAlreadyDefinedError, 'a13g/errors'
|
39
|
+
|
40
|
+
def self.method_missing(meth, *args, &block)
|
41
|
+
if Base.respond_to?(meth)
|
42
|
+
Base.send(meth, *args, &block)
|
43
|
+
else
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# @see A13g::Listener#start
|
49
|
+
# @api public
|
50
|
+
def self.listen!
|
51
|
+
Listener.start!
|
52
|
+
end
|
53
|
+
|
54
|
+
# Current version.
|
55
|
+
#
|
56
|
+
# @api public
|
57
|
+
def self.version
|
58
|
+
VERSION::STRING
|
59
|
+
end
|
60
|
+
|
61
|
+
extend Producer
|
62
|
+
|
63
|
+
module ConnectionAdapters
|
64
|
+
autoload :BrokerStatements, "a13g/connection_adapters/abstract/broker_statements"
|
65
|
+
autoload :ConnectionSpecification, "a13g/connection_adapters/abstract/connection_specification"
|
66
|
+
autoload :ConnectionPool, "a13g/connection_adapters/abstract/connection_pool"
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module A13g
|
2
|
+
module Adapters
|
3
|
+
# Register new adapter.
|
4
|
+
#
|
5
|
+
# @param [String, Symbol] name
|
6
|
+
# name of adapter
|
7
|
+
# @param [Class] klass
|
8
|
+
# adapter class
|
9
|
+
#
|
10
|
+
# @api public
|
11
|
+
def self.register(name, klass)
|
12
|
+
available_adapters[name.to_s] = klass
|
13
|
+
end
|
14
|
+
|
15
|
+
# Loads specified adapter from rubygems or directly from A13g.
|
16
|
+
#
|
17
|
+
# @param [String] name
|
18
|
+
# adapter to load
|
19
|
+
#
|
20
|
+
# @api public
|
21
|
+
def self.load(name)
|
22
|
+
unless available_adapters[name.to_s]
|
23
|
+
begin
|
24
|
+
require "a13g-#{name}-adapter"
|
25
|
+
rescue LoadError
|
26
|
+
begin
|
27
|
+
require File.join(File.dirname(__FILE__), "adapters/#{name}_adapter.rb")
|
28
|
+
rescue LoadError
|
29
|
+
raise AdapterNotFound, "Adapter `#{name}` not is not defned"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
available_adapters[name.to_s]
|
34
|
+
end
|
35
|
+
|
36
|
+
# List of available connection adapters.
|
37
|
+
#
|
38
|
+
# @return [Hash]
|
39
|
+
#
|
40
|
+
# @api public
|
41
|
+
def self.available_adapters
|
42
|
+
@available_adapters ||= {}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,330 @@
|
|
1
|
+
module A13g
|
2
|
+
module Adapters
|
3
|
+
# Base class for adapters. All connection adapters should inherit from this one.
|
4
|
+
#
|
5
|
+
# === Writing own adapter
|
6
|
+
#
|
7
|
+
# When you write some new connection adapter, you should use following
|
8
|
+
# code as base:
|
9
|
+
#
|
10
|
+
# module A13g
|
11
|
+
# module Adapters
|
12
|
+
# class HumptyDumptyAdapter < AbstractAdapter
|
13
|
+
# register(:humpty_dumpty) # register new adapter as `humpty_dumpty`
|
14
|
+
#
|
15
|
+
# # Your adapter code...
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
class AbstractAdapter
|
20
|
+
include ActiveSupport::Callbacks
|
21
|
+
|
22
|
+
attr_reader :logger, :config
|
23
|
+
attr_reader :subscriptions, :transactions
|
24
|
+
attr_reader :last_published_message
|
25
|
+
attr_reader :last_received_message, :last_unreceived_message
|
26
|
+
|
27
|
+
define_callbacks :after_subscribe, :after_unsubscribe, :after_publish,
|
28
|
+
:after_receive, :after_unreceive, :after_abort_transaction,
|
29
|
+
:after_begin_transaction, :after_commit_transaction, :after_ack
|
30
|
+
|
31
|
+
after_subscribe do |obj, destination, headers, sub_id|
|
32
|
+
sub_id ||= destination.to_s
|
33
|
+
obj.subscriptions[sub_id] = OpenStruct.new(
|
34
|
+
:destination => destination.to_s,
|
35
|
+
:headers => headers
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
after_unsubscribe do |obj, destination, headers, sub_id|
|
40
|
+
sub_id ||= destination.to_s
|
41
|
+
obj.subscriptions.delete(sub_id)
|
42
|
+
end
|
43
|
+
|
44
|
+
after_publish do |obj, destination, message, headers|
|
45
|
+
msg = OpenStruct.new(
|
46
|
+
:destination => destination,
|
47
|
+
:message => message,
|
48
|
+
:headers => headers
|
49
|
+
)
|
50
|
+
obj.instance_variable_set('@last_published_message', msg)
|
51
|
+
end
|
52
|
+
|
53
|
+
after_receive do |obj, message|
|
54
|
+
obj.instance_variable_set('@last_received_message', message)
|
55
|
+
end
|
56
|
+
|
57
|
+
after_unreceive do |obj, message|
|
58
|
+
msg = message.clone
|
59
|
+
msg.headers.merge!(defaults)
|
60
|
+
obj.instance_variable_set('@last_unreceived_message', msg)
|
61
|
+
end
|
62
|
+
|
63
|
+
after_begin_transaction do |obj, name, headers|
|
64
|
+
obj.transactions[name] = OpenStruct.new(
|
65
|
+
:name => name,
|
66
|
+
:headers => headers
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
after_abort_transaction do |obj, name, headers|
|
71
|
+
obj.transactions.delete(name)
|
72
|
+
end
|
73
|
+
|
74
|
+
after_commit_transaction do |obj, name, headers|
|
75
|
+
obj.transactions.delete(name)
|
76
|
+
end
|
77
|
+
|
78
|
+
after_ack do |obj, message, headers|
|
79
|
+
message.ack = true if message.respond_to?(:ack=)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Little bit changed running callbacks. It allows to pass more than one
|
83
|
+
# parameter to block.
|
84
|
+
#
|
85
|
+
# @api public
|
86
|
+
def run_callbacks(kind, params=[], options = {}, &block)
|
87
|
+
params.unshift(self)
|
88
|
+
self.class.send("#{kind}_callback_chain").run(params, options, &block)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Constructor.
|
92
|
+
#
|
93
|
+
# @param [Hash] config
|
94
|
+
# connection configuration
|
95
|
+
#
|
96
|
+
# @param [Logger] logger
|
97
|
+
# default logger
|
98
|
+
#
|
99
|
+
# @api public
|
100
|
+
def initialize(config, logger)
|
101
|
+
@config = config.freeze
|
102
|
+
@logger = logger
|
103
|
+
@runtime = 0
|
104
|
+
@last_verification = 0
|
105
|
+
@subscriptions = {}
|
106
|
+
@transactions = {}
|
107
|
+
end
|
108
|
+
|
109
|
+
# Connection url.
|
110
|
+
#
|
111
|
+
# @api public
|
112
|
+
def url
|
113
|
+
"#{@config[:host]}:#{@config[:port]}" if @config
|
114
|
+
end
|
115
|
+
|
116
|
+
# @api public
|
117
|
+
def adapter_name
|
118
|
+
'Abstract'.freeze
|
119
|
+
end
|
120
|
+
|
121
|
+
# @api public
|
122
|
+
def reset_runtime
|
123
|
+
rt, @runtime = @runtime, 0
|
124
|
+
rt
|
125
|
+
end
|
126
|
+
|
127
|
+
# Akcnowledge for specified message.
|
128
|
+
#
|
129
|
+
# @param [A13g::Message] message
|
130
|
+
# message to acknowledge
|
131
|
+
#
|
132
|
+
# @param [Hash] headers
|
133
|
+
# acknowledgement headers
|
134
|
+
#
|
135
|
+
# @param [Array] args
|
136
|
+
# additional arguments
|
137
|
+
#
|
138
|
+
# @api public
|
139
|
+
def ack(message, headers={}, *args)
|
140
|
+
raise NotImplementedError, "#{self.class}#ack not implemented"
|
141
|
+
end
|
142
|
+
alias_method :acknowledge, :ack
|
143
|
+
|
144
|
+
# Begin transaction.
|
145
|
+
#
|
146
|
+
# @param [String] name
|
147
|
+
# transaction id
|
148
|
+
#
|
149
|
+
# @param [Hash] headers
|
150
|
+
# transaction headers
|
151
|
+
#
|
152
|
+
# @param [Array] args
|
153
|
+
# additional arguments
|
154
|
+
#
|
155
|
+
# @api public
|
156
|
+
def begin(name, headers={}, *args)
|
157
|
+
raise NotImplementedError, "#{self.class}#begin not implemented"
|
158
|
+
end
|
159
|
+
|
160
|
+
# Commit transaction. Parameters the same as #begin method.
|
161
|
+
#
|
162
|
+
# @see A13g::Adapters::AbstractAdapter#begin
|
163
|
+
#
|
164
|
+
# @api public
|
165
|
+
def commit(name, headers={}, *args)
|
166
|
+
raise NotImplementedError, "#{self.class}#commit not implemented"
|
167
|
+
end
|
168
|
+
|
169
|
+
# Abort transaction. Parameters the same as #begin method.
|
170
|
+
#
|
171
|
+
# @see A13g::Adapters::AbstractAdapter#begin
|
172
|
+
#
|
173
|
+
# @api public
|
174
|
+
def abort(name, headers={}, *args)
|
175
|
+
raise NotImplementedError, "#{self.class}#abort not implemented"
|
176
|
+
end
|
177
|
+
|
178
|
+
# Subscribe specified queue/topic.
|
179
|
+
#
|
180
|
+
# @param [String] destination
|
181
|
+
# destination to subscribe
|
182
|
+
#
|
183
|
+
# @param [Hash] headers
|
184
|
+
# subscription headers
|
185
|
+
#
|
186
|
+
# @param [Array] args
|
187
|
+
# additional arguments
|
188
|
+
#
|
189
|
+
# @api public
|
190
|
+
def subsrcibe(destination, headers={}, *args)
|
191
|
+
raise NotImplementedError, "#{self.class}#subsrcibe not implemented"
|
192
|
+
end
|
193
|
+
|
194
|
+
# Unsubscribe specified queue/topic. Params the same as #subscription method.
|
195
|
+
#
|
196
|
+
# @see A13g::Adapters::AbstractAdapter#subscription
|
197
|
+
#
|
198
|
+
# @api public
|
199
|
+
def unsubscribe(destination, headers={}, *args)
|
200
|
+
raise NotImplementedError, "#{self.class}#unsubscribe not implemented"
|
201
|
+
end
|
202
|
+
|
203
|
+
# Publish message to specified destination.
|
204
|
+
#
|
205
|
+
# @param [String] destination
|
206
|
+
# destination name
|
207
|
+
#
|
208
|
+
# @param [String] message
|
209
|
+
# text to send
|
210
|
+
#
|
211
|
+
# @param [Hash] headers
|
212
|
+
# message headers
|
213
|
+
#
|
214
|
+
# @param [Array] args
|
215
|
+
# additional arguments
|
216
|
+
#
|
217
|
+
# @api public
|
218
|
+
def publish(destination, message, headers={}, *args)
|
219
|
+
raise NotImplementedError, "#{self.class}#publish not implemented"
|
220
|
+
end
|
221
|
+
|
222
|
+
# Set message as unreceived. Parameters the same as #ack method.
|
223
|
+
#
|
224
|
+
# @see A13g::Adapters::AbstractAdapter#ack
|
225
|
+
#
|
226
|
+
# @api public
|
227
|
+
def unreceive(message, headers={}, *args)
|
228
|
+
raise NotImplementedError, "#{self.class}#unreceive not implemented"
|
229
|
+
end
|
230
|
+
|
231
|
+
# Check message acknowledgement.
|
232
|
+
#
|
233
|
+
# @param [A13g::Message] message
|
234
|
+
# received message
|
235
|
+
#
|
236
|
+
# @param [Array] args
|
237
|
+
# additional arguments
|
238
|
+
#
|
239
|
+
# @api public
|
240
|
+
def client_ack?(message, *args)
|
241
|
+
raise NotImplementedError, "#{self.class}#client_ack? not implemented"
|
242
|
+
end
|
243
|
+
|
244
|
+
# Receive messages from subscribed queues.
|
245
|
+
#
|
246
|
+
# @param [Array] args
|
247
|
+
# additional arguments
|
248
|
+
#
|
249
|
+
# @return [A13g::Message]
|
250
|
+
# received message
|
251
|
+
#
|
252
|
+
# @api public
|
253
|
+
def receive(*args)
|
254
|
+
raise NotImplementedError, "#{self.class}#receive not implemented"
|
255
|
+
end
|
256
|
+
|
257
|
+
# Checks whether the connection to the database is still active. This includes
|
258
|
+
# checking whether the database is actually capable of responding, i.e. whether
|
259
|
+
# the connection isn't stale.
|
260
|
+
#
|
261
|
+
# @return [Boolean]
|
262
|
+
# is connection active?
|
263
|
+
#
|
264
|
+
# @api public
|
265
|
+
def active?
|
266
|
+
@active != false
|
267
|
+
end
|
268
|
+
|
269
|
+
# Disconnects from the broker if already connected, and establishes a
|
270
|
+
# new connection with the broker.
|
271
|
+
#
|
272
|
+
# @api public
|
273
|
+
def reconnect!
|
274
|
+
@active = true
|
275
|
+
end
|
276
|
+
|
277
|
+
# Disconnects from the broker if already connected. Otherwise, this
|
278
|
+
# method does nothing.
|
279
|
+
#
|
280
|
+
# @api public
|
281
|
+
def disconnect!
|
282
|
+
@active = false
|
283
|
+
end
|
284
|
+
|
285
|
+
# Reset the state of this connection.
|
286
|
+
#
|
287
|
+
# The default implementation does nothing; the implementation should be
|
288
|
+
# overridden by concrete adapters.
|
289
|
+
#
|
290
|
+
# @api public
|
291
|
+
def reset!
|
292
|
+
# this should be overridden by concrete adapters
|
293
|
+
end
|
294
|
+
|
295
|
+
# Returns `true` if its safe to reload the connection between requests for development mode.
|
296
|
+
#
|
297
|
+
# @return [Boolean]
|
298
|
+
#
|
299
|
+
# @api public
|
300
|
+
def requires_reloading?
|
301
|
+
false
|
302
|
+
end
|
303
|
+
|
304
|
+
# Checks whether the connection to the broker is still active (i.e. not stale).
|
305
|
+
# This is done under the hood by calling <tt>active?</tt>. If the connection
|
306
|
+
# is no longer active, then this method will reconnect to the broker.
|
307
|
+
#
|
308
|
+
# @api public
|
309
|
+
def verify!(*ignored)
|
310
|
+
unless active?
|
311
|
+
logger.error("*** No active connection with broker at #{url}. Trying to reconnect...")
|
312
|
+
reconnect!
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
protected
|
317
|
+
|
318
|
+
# Provides access to the underlying broker driver for this adapter.
|
319
|
+
#
|
320
|
+
# @return [Object]
|
321
|
+
# direct connection object
|
322
|
+
#
|
323
|
+
# @api semipublic
|
324
|
+
def raw_connection
|
325
|
+
verify!
|
326
|
+
@connection
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|