orientdb4r 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/changelog.txt +4 -0
- data/fstudy/flat_class_perf.rb +1 -1
- data/lib/orientdb4r/client.rb +16 -2
- data/lib/orientdb4r/load_balancing.rb +25 -3
- data/lib/orientdb4r/rest/client.rb +17 -5
- data/lib/orientdb4r/rest/excon_node.rb +11 -4
- data/lib/orientdb4r/version.rb +1 -0
- data/lib/orientdb4r.rb +0 -15
- data/test/test_client.rb +86 -0
- data/test/{test_distributed.rb → test_loadbalancing.rb} +5 -25
- data/test/test_utils.rb +1 -1
- metadata +7 -5
data/changelog.txt
CHANGED
data/fstudy/flat_class_perf.rb
CHANGED
data/lib/orientdb4r/client.rb
CHANGED
@@ -9,10 +9,23 @@ module Orientdb4r
|
|
9
9
|
# # Regexp to validate format of providet version.
|
10
10
|
SERVER_VERSION_PATTERN = /^\d+\.\d+\.\d+/
|
11
11
|
|
12
|
+
# connection parameters
|
12
13
|
attr_reader :user, :password, :database
|
14
|
+
# version loaded from server
|
13
15
|
attr_reader :server_version
|
14
|
-
|
15
|
-
attr_reader :
|
16
|
+
# type of connection library [:restclient, :excon]
|
17
|
+
attr_reader :connection_library
|
18
|
+
# type of load balancing [:sequence, :round_robin]
|
19
|
+
attr_reader :load_balancing
|
20
|
+
# proxy for remote communication
|
21
|
+
attr_reader :proxy
|
22
|
+
|
23
|
+
# intern structures
|
24
|
+
|
25
|
+
# nodes responsible for communication with a server
|
26
|
+
attr_reader :nodes
|
27
|
+
# object implementing a LB strategy
|
28
|
+
attr_reader :lb_strategy
|
16
29
|
|
17
30
|
###
|
18
31
|
# Constructor.
|
@@ -282,6 +295,7 @@ module Orientdb4r
|
|
282
295
|
|
283
296
|
rescue NodeError => e
|
284
297
|
Orientdb4r::logger.error "node error, index=#{idx}, msg=#{e.message}, #{node}"
|
298
|
+
node.cleanup
|
285
299
|
lb_strategy.bad_one idx
|
286
300
|
idx = lb_strategy.node_index
|
287
301
|
end
|
@@ -4,7 +4,7 @@ module Orientdb4r
|
|
4
4
|
# Base class for implementation of load balancing strategy.
|
5
5
|
class LBStrategy
|
6
6
|
|
7
|
-
# If occures a new try to communicate from node can be tested.
|
7
|
+
# If occures a new try to communicate from node can be tested [s].
|
8
8
|
RECOVERY_TIMEOUT = 30
|
9
9
|
|
10
10
|
attr_reader :nodes_count, :bad_nodes
|
@@ -39,17 +39,39 @@ module Orientdb4r
|
|
39
39
|
|
40
40
|
protected
|
41
41
|
|
42
|
+
###
|
43
|
+
# Tries to find a new node if the given failed.
|
44
|
+
# Returns <i>nil</i> if no one found
|
42
45
|
def search_next_good(bad_idx)
|
43
46
|
Orientdb4r::logger.warn "identified bad node, idx=#{bad_idx}, age=#{Time.now - @bad_nodes[bad_idx]} [s]"
|
47
|
+
|
48
|
+
# alternative nodes of not found a good one
|
49
|
+
timeout_candidate = nil
|
50
|
+
|
51
|
+
# first round - try to find a first good one
|
44
52
|
1.upto(nodes_count) do |i|
|
45
53
|
candidate = (i + bad_idx) % nodes_count
|
46
|
-
|
54
|
+
|
55
|
+
if @bad_nodes.include? candidate
|
56
|
+
failure_time = @bad_nodes[candidate]
|
57
|
+
now = Time.now
|
58
|
+
# timeout candidate
|
59
|
+
if (now - failure_time) > RECOVERY_TIMEOUT
|
60
|
+
timeout_candidate = candidate
|
61
|
+
Orientdb4r::logger.debug "node timeout recovery, idx=#{candidate}"
|
62
|
+
good_one(candidate)
|
63
|
+
end
|
64
|
+
else
|
47
65
|
Orientdb4r::logger.debug "found good node, idx=#{candidate}"
|
48
66
|
return candidate
|
49
67
|
end
|
50
68
|
end
|
51
69
|
|
52
|
-
#
|
70
|
+
# no good index found -> try timeouted one
|
71
|
+
unless timeout_candidate.nil?
|
72
|
+
Orientdb4r::logger.debug "good node not found, delivering timeouted one, idx=#{timeout_candidate}"
|
73
|
+
return timeout_candidate
|
74
|
+
end
|
53
75
|
|
54
76
|
Orientdb4r::logger.error 'no nodes more, all invalid'
|
55
77
|
nil
|
@@ -12,18 +12,22 @@ module Orientdb4r
|
|
12
12
|
|
13
13
|
def initialize(options) #:nodoc:
|
14
14
|
super()
|
15
|
-
options_pattern = {
|
16
|
-
|
17
|
-
|
15
|
+
options_pattern = {
|
16
|
+
:host => 'localhost', :port => 2480, :ssl => false,
|
17
|
+
:nodes => :optional,
|
18
|
+
:connection_library => :restclient,
|
19
|
+
:load_balancing => :sequence,
|
20
|
+
:proxy => :optional
|
21
|
+
}
|
18
22
|
verify_and_sanitize_options(options, options_pattern)
|
19
23
|
|
20
24
|
# fake nodes for single server
|
21
25
|
if options[:nodes].nil?
|
22
26
|
options[:nodes] = [{:host => options[:host], :port => options[:port], :ssl => options[:ssl]}]
|
23
27
|
end
|
24
|
-
raise ArgumentError, 'nodes has to be
|
28
|
+
raise ArgumentError, 'nodes has to be array' unless options[:nodes].is_a? Array
|
25
29
|
|
26
|
-
# instantiate nodes
|
30
|
+
# instantiate nodes according to HTTP library
|
27
31
|
@connection_library = options[:connection_library]
|
28
32
|
node_clazz = case connection_library
|
29
33
|
when :restclient then Orientdb4r::RestClientNode
|
@@ -45,6 +49,14 @@ module Orientdb4r
|
|
45
49
|
else raise ArgumentError, "unknow load balancing type: #{load_balancing}"
|
46
50
|
end
|
47
51
|
|
52
|
+
# proxy
|
53
|
+
@proxy = options[:proxy]
|
54
|
+
unless proxy.nil?
|
55
|
+
case connection_library
|
56
|
+
when :restclient then ::RestClient.proxy = proxy
|
57
|
+
when :excon then nodes.each { |node| node.proxy = proxy }
|
58
|
+
end
|
59
|
+
end
|
48
60
|
|
49
61
|
Orientdb4r::logger.info "client initialized with #{@nodes.size} node(s) "
|
50
62
|
Orientdb4r::logger.info "connection_library=#{options[:connection_library]}, load_balancing=#{load_balancing}"
|
@@ -7,6 +7,8 @@ module Orientdb4r
|
|
7
7
|
# accessible view REST API and 'excon' library on the client side.
|
8
8
|
class ExconNode < RestNode
|
9
9
|
|
10
|
+
attr_accessor :proxy
|
11
|
+
|
10
12
|
def request(options) #:nodoc:
|
11
13
|
verify_options(options, {:user => :mandatory, :password => :mandatory, \
|
12
14
|
:uri => :mandatory, :method => :mandatory, :content_type => :optional, :data => :optional})
|
@@ -77,10 +79,15 @@ module Orientdb4r
|
|
77
79
|
###
|
78
80
|
# Gets Excon connection.
|
79
81
|
def connection
|
80
|
-
@connection
|
81
|
-
|
82
|
-
|
83
|
-
|
82
|
+
return @connection unless @connection.nil?
|
83
|
+
|
84
|
+
options = {}
|
85
|
+
options[:proxy] = proxy unless proxy.nil?
|
86
|
+
|
87
|
+
@connection ||= Excon::Connection.new(url, options)
|
88
|
+
#:read_timeout => self.class.read_timeout,
|
89
|
+
#:write_timeout => self.class.write_timeout,
|
90
|
+
#:connect_timeout => self.class.connect_timeout
|
84
91
|
end
|
85
92
|
|
86
93
|
###
|
data/lib/orientdb4r/version.rb
CHANGED
@@ -2,6 +2,7 @@ module Orientdb4r
|
|
2
2
|
|
3
3
|
# Version history.
|
4
4
|
VERSION_HISTORY = [
|
5
|
+
['0.3.1', '2012-08-27', "Timeout for reuse of dirty nodes in load balancing; BF #14, BF #15"],
|
5
6
|
['0.3.0', '2012-08-01', "Added support for cluster of distributed servers + load balancing"],
|
6
7
|
['0.2.10', '2012-07-21', "Experimental support for Excon HTTP library with Keep-Alive connection"],
|
7
8
|
['0.2.9', '2012-07-18', "Added feature Client#delete_database, New class Rid"],
|
data/lib/orientdb4r.rb
CHANGED
@@ -40,21 +40,10 @@ module Orientdb4r
|
|
40
40
|
}
|
41
41
|
end
|
42
42
|
|
43
|
-
###
|
44
|
-
# All calls to REST API will use the proxy specified here.
|
45
|
-
def rest_proxy(url)
|
46
|
-
RestClient.proxy = url
|
47
|
-
end
|
48
|
-
|
49
43
|
###
|
50
44
|
# Logger used for logging output
|
51
45
|
attr_accessor :logger
|
52
46
|
|
53
|
-
###
|
54
|
-
# Predefined connection library.
|
55
|
-
# Can be overriden by option in client initialization.
|
56
|
-
attr_accessor :connection_library
|
57
|
-
|
58
47
|
end
|
59
48
|
|
60
49
|
|
@@ -99,10 +88,6 @@ end
|
|
99
88
|
Orientdb4r::logger = Logger.new(STDOUT)
|
100
89
|
Orientdb4r::logger.level = Logger::INFO
|
101
90
|
|
102
|
-
# Default connection library
|
103
|
-
Orientdb4r::connection_library = :restclient
|
104
|
-
#Orientdb4r::connection_library = :excon
|
105
|
-
|
106
91
|
Orientdb4r::logger.info \
|
107
92
|
"Orientdb4r #{Orientdb4r::VERSION}, running on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
|
108
93
|
|
data/test/test_client.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'orientdb4r'
|
3
|
+
|
4
|
+
###
|
5
|
+
# This class tests communication with OrientDB cluster and load balancing.
|
6
|
+
class TestClient < Test::Unit::TestCase
|
7
|
+
|
8
|
+
Orientdb4r::logger.level = Logger::DEBUG
|
9
|
+
|
10
|
+
PROXY_URL = 'http://bad.domain.com'
|
11
|
+
|
12
|
+
|
13
|
+
###
|
14
|
+
# Test inintialization of single node.
|
15
|
+
def test_one_node_initialization
|
16
|
+
client = Orientdb4r.client :instance => :new
|
17
|
+
assert_not_nil client.nodes
|
18
|
+
assert_instance_of Array, client.nodes
|
19
|
+
assert_equal 1, client.nodes.size
|
20
|
+
assert_equal 2480, client.nodes[0].port
|
21
|
+
assert_equal false, client.nodes[0].ssl
|
22
|
+
end
|
23
|
+
|
24
|
+
###
|
25
|
+
# Test inintialization of more nodes.
|
26
|
+
def test_nodes_initialization
|
27
|
+
client = Orientdb4r.client :nodes => [{}, {:port => 2481}], :instance => :new
|
28
|
+
assert_not_nil client.nodes
|
29
|
+
assert_instance_of Array, client.nodes
|
30
|
+
assert_equal 2, client.nodes.size
|
31
|
+
assert_equal 2480, client.nodes[0].port
|
32
|
+
assert_equal 2481, client.nodes[1].port
|
33
|
+
assert_equal false, client.nodes[0].ssl
|
34
|
+
assert_equal false, client.nodes[1].ssl
|
35
|
+
|
36
|
+
client = Orientdb4r.client :nodes => [{}, {:port => 2481}, {:port => 2482}], :instance => :new
|
37
|
+
assert_equal 3, client.nodes.size
|
38
|
+
end
|
39
|
+
|
40
|
+
###
|
41
|
+
# Tests initialization of connection library.
|
42
|
+
def test_connection_library
|
43
|
+
# restclient
|
44
|
+
client = Orientdb4r.client :instance => :new
|
45
|
+
assert_equal :restclient, client.connection_library
|
46
|
+
assert_instance_of Orientdb4r::RestClientNode, client.nodes[0]
|
47
|
+
|
48
|
+
# excon
|
49
|
+
client = Orientdb4r.client :connection_library => :excon, :instance => :new
|
50
|
+
assert_equal :excon, client.connection_library
|
51
|
+
assert_instance_of Orientdb4r::ExconNode, client.nodes[0]
|
52
|
+
end
|
53
|
+
|
54
|
+
###
|
55
|
+
# Tests initialization of proxy.
|
56
|
+
def test_proxy
|
57
|
+
# no proxy - resclient
|
58
|
+
client = Orientdb4r.client :instance => :new
|
59
|
+
assert_nil client.proxy
|
60
|
+
assert_nil RestClient.proxy
|
61
|
+
|
62
|
+
# proxy - restclient
|
63
|
+
client = Orientdb4r.client :proxy => PROXY_URL, :instance => :new
|
64
|
+
assert_equal PROXY_URL, client.proxy
|
65
|
+
assert_equal PROXY_URL, RestClient.proxy
|
66
|
+
assert_raise Orientdb4r::ConnectionError do
|
67
|
+
client.connect :database => 'temp', :user => 'admin', :password => 'admin'
|
68
|
+
end
|
69
|
+
RestClient.proxy = nil # restore no setting
|
70
|
+
|
71
|
+
# no proxy - excon
|
72
|
+
client = Orientdb4r.client :connection_library => :excon, :instance => :new
|
73
|
+
assert_nil client.proxy
|
74
|
+
assert_nil client.nodes[0].proxy
|
75
|
+
|
76
|
+
# proxy - restclient
|
77
|
+
client = Orientdb4r.client :connection_library => :excon, :proxy => PROXY_URL, :instance => :new
|
78
|
+
assert_equal PROXY_URL, client.proxy
|
79
|
+
assert_equal PROXY_URL, client.nodes[0].proxy
|
80
|
+
assert_raise Orientdb4r::ConnectionError do
|
81
|
+
client.connect :database => 'temp', :user => 'admin', :password => 'admin'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
end
|
@@ -3,39 +3,16 @@ require 'orientdb4r'
|
|
3
3
|
|
4
4
|
###
|
5
5
|
# This class tests communication with OrientDB cluster and load balancing.
|
6
|
-
class
|
6
|
+
class TestLoadBalancing < Test::Unit::TestCase
|
7
7
|
|
8
8
|
Orientdb4r::logger.level = Logger::DEBUG
|
9
9
|
|
10
10
|
|
11
|
-
###
|
12
|
-
# Test inintialization of single node.
|
13
|
-
def test_one_node_initialization
|
14
|
-
client = Orientdb4r.client :instance => :new
|
15
|
-
assert_not_nil client.nodes
|
16
|
-
assert_instance_of Array, client.nodes
|
17
|
-
assert_equal 1, client.nodes.size
|
18
|
-
assert_equal 2480, client.nodes[0].port
|
19
|
-
assert_equal false, client.nodes[0].ssl
|
20
|
-
end
|
21
|
-
|
22
|
-
###
|
23
|
-
# Test inintialization of more nodes.
|
24
|
-
def test_nodes_initialization
|
25
|
-
client = Orientdb4r.client :nodes => [{}, {:port => 2481}], :instance => :new
|
26
|
-
assert_not_nil client.nodes
|
27
|
-
assert_instance_of Array, client.nodes
|
28
|
-
assert_equal 2, client.nodes.size
|
29
|
-
assert_equal 2480, client.nodes[0].port
|
30
|
-
assert_equal 2481, client.nodes[1].port
|
31
|
-
assert_equal false, client.nodes[0].ssl
|
32
|
-
assert_equal false, client.nodes[1].ssl
|
33
|
-
end
|
34
|
-
|
35
11
|
###
|
36
12
|
# Test default Sequence strategy.
|
37
13
|
def test_sequence_loadbalancing
|
38
14
|
client = Orientdb4r.client :nodes => [{}, {:port => 2481}], :instance => :new
|
15
|
+
assert_equal :sequence, client.load_balancing
|
39
16
|
lb_strategy = client.lb_strategy
|
40
17
|
assert_not_nil lb_strategy
|
41
18
|
assert_instance_of Orientdb4r::Sequence, lb_strategy
|
@@ -49,6 +26,7 @@ class TestDatabase < Test::Unit::TestCase
|
|
49
26
|
# Test RoundRobin strategy.
|
50
27
|
def test_roundrobin_loadbalancing
|
51
28
|
client = Orientdb4r.client :nodes => [{}, {:port => 2481}], :load_balancing => :round_robin, :instance => :new
|
29
|
+
assert_equal :round_robin, client.load_balancing
|
52
30
|
lb_strategy = client.lb_strategy
|
53
31
|
assert_not_nil lb_strategy
|
54
32
|
assert_instance_of Orientdb4r::RoundRobin, lb_strategy
|
@@ -60,6 +38,8 @@ class TestDatabase < Test::Unit::TestCase
|
|
60
38
|
assert_equal client.nodes[1], client.nodes[client.lb_strategy.node_index]
|
61
39
|
end
|
62
40
|
|
41
|
+
###
|
42
|
+
# Tests variant reasons for LB failure.
|
63
43
|
def test_load_balancing_in_problems
|
64
44
|
# invalid port
|
65
45
|
client = Orientdb4r.client :port => 9999, :instance => :new
|
data/test/test_utils.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: orientdb4r
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|
@@ -65,11 +65,12 @@ files:
|
|
65
65
|
- lib/orientdb4r/version.rb
|
66
66
|
- orientdb4r.gemspec
|
67
67
|
- test/readme_sample.rb
|
68
|
+
- test/test_client.rb
|
68
69
|
- test/test_database.rb
|
69
70
|
- test/test_ddo.rb
|
70
|
-
- test/test_distributed.rb
|
71
71
|
- test/test_dmo.rb
|
72
72
|
- test/test_document_crud.rb
|
73
|
+
- test/test_loadbalancing.rb
|
73
74
|
- test/test_utils.rb
|
74
75
|
homepage: http://github.com/veny/orientdb4r
|
75
76
|
licenses: []
|
@@ -92,15 +93,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
93
|
version: 1.3.1
|
93
94
|
requirements: []
|
94
95
|
rubyforge_project:
|
95
|
-
rubygems_version: 1.8.
|
96
|
+
rubygems_version: 1.8.23
|
96
97
|
signing_key:
|
97
98
|
specification_version: 3
|
98
99
|
summary: Ruby binding for Orient DB.
|
99
100
|
test_files:
|
100
101
|
- test/readme_sample.rb
|
102
|
+
- test/test_client.rb
|
101
103
|
- test/test_database.rb
|
102
104
|
- test/test_ddo.rb
|
103
|
-
- test/test_distributed.rb
|
104
105
|
- test/test_dmo.rb
|
105
106
|
- test/test_document_crud.rb
|
107
|
+
- test/test_loadbalancing.rb
|
106
108
|
- test/test_utils.rb
|