a13g 0.1.0.beta3 → 0.1.0.beta4
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.
- 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
|