oedipus 0.0.4 → 0.0.5
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/lib/oedipus/connection/pool.rb +109 -0
- data/lib/oedipus/connection.rb +20 -4
- data/lib/oedipus/version.rb +1 -1
- data/lib/oedipus.rb +1 -0
- data/spec/integration/connection_spec.rb +0 -2
- metadata +8 -7
@@ -0,0 +1,109 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
##
|
4
|
+
# Oedipus Sphinx 2 Search.
|
5
|
+
# Copyright © 2012 Chris Corbyn.
|
6
|
+
#
|
7
|
+
# See LICENSE file for details.
|
8
|
+
##
|
9
|
+
|
10
|
+
require "thread"
|
11
|
+
|
12
|
+
module Oedipus
|
13
|
+
class Connection
|
14
|
+
# Provides a thread-safe pool of connections, with a specified TTL.
|
15
|
+
class Pool
|
16
|
+
# Initialize a new connection pool with the given options.
|
17
|
+
#
|
18
|
+
# @param [Hash] options
|
19
|
+
# configuration for the pool
|
20
|
+
#
|
21
|
+
# @option [String] host
|
22
|
+
# the host to use when allocating new connections
|
23
|
+
#
|
24
|
+
# @option [Fixnum] port
|
25
|
+
# the port to use when allocating new connections
|
26
|
+
#
|
27
|
+
# @option [Fixnum] size
|
28
|
+
# the maximum number of connections (defaults to 8)
|
29
|
+
#
|
30
|
+
# @option [Fixnum] ttl
|
31
|
+
# the length of time for which any given connection should live
|
32
|
+
def initialize(options)
|
33
|
+
@host = options[:host]
|
34
|
+
@port = options[:port]
|
35
|
+
|
36
|
+
@size = options.fetch(:size, 8)
|
37
|
+
@ttl = options.fetch(:ttl, 60)
|
38
|
+
|
39
|
+
@available = []
|
40
|
+
@used = {}
|
41
|
+
@expiries = {}
|
42
|
+
@condition = ConditionVariable.new
|
43
|
+
@lock = Mutex.new
|
44
|
+
|
45
|
+
sweeper
|
46
|
+
end
|
47
|
+
|
48
|
+
# Acquire a connection from the pool, for the duration of a block.
|
49
|
+
#
|
50
|
+
# The release of the connection is done automatically.
|
51
|
+
#
|
52
|
+
# @yields [Oedipus::Mysql]
|
53
|
+
# a connection object
|
54
|
+
def acquire
|
55
|
+
instance = nil
|
56
|
+
begin
|
57
|
+
@lock.synchronize do
|
58
|
+
if instance = @available.pop
|
59
|
+
@used[instance] = instance
|
60
|
+
elsif @size > (@available.size + @used.size)
|
61
|
+
instance = new_instance
|
62
|
+
else
|
63
|
+
@condition.wait(@lock)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end until instance
|
67
|
+
|
68
|
+
yield instance
|
69
|
+
ensure
|
70
|
+
release(instance)
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def release(instance)
|
76
|
+
@lock.synchronize do
|
77
|
+
@available << @used.delete(instance) if instance
|
78
|
+
@condition.broadcast
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def new_instance
|
83
|
+
Oedipus::Mysql.new(@host, @port).tap do |instance|
|
84
|
+
@used[instance] = instance
|
85
|
+
@expiries[instance] = Time.now + @ttl
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Close connections past their ttl (runs in a new Thread)
|
90
|
+
def sweeper
|
91
|
+
Thread.new(@expiries, @available) do |exp, avail|
|
92
|
+
loop do
|
93
|
+
sleep 15
|
94
|
+
@lock.synchronize {
|
95
|
+
avail.each do |instance|
|
96
|
+
if exp[instance] < Time.now
|
97
|
+
avail.delete(instance)
|
98
|
+
exp.delete(instance)
|
99
|
+
instance.close
|
100
|
+
end
|
101
|
+
end
|
102
|
+
}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/lib/oedipus/connection.rb
CHANGED
@@ -65,11 +65,21 @@ module Oedipus
|
|
65
65
|
# a Hash containing :host and :port
|
66
66
|
#
|
67
67
|
# The connection will be established on initialization.
|
68
|
+
#
|
69
|
+
# The underlying implementation uses a thread-safe connection pool.
|
68
70
|
def initialize(options)
|
69
71
|
options = options.kind_of?(String) ?
|
70
72
|
Hash[ [:host, :port].zip(options.split(":")) ] :
|
71
73
|
options
|
72
|
-
|
74
|
+
|
75
|
+
@pool = Pool.new(
|
76
|
+
host: options[:host],
|
77
|
+
port: options[:port].to_i,
|
78
|
+
size: options.fetch(:pool_size, 8),
|
79
|
+
ttl: 60
|
80
|
+
)
|
81
|
+
|
82
|
+
assert_valid_pool
|
73
83
|
end
|
74
84
|
|
75
85
|
# Acess a specific index for querying.
|
@@ -96,7 +106,7 @@ module Oedipus
|
|
96
106
|
#
|
97
107
|
# Note that SphinxQL does not support prepared statements.
|
98
108
|
def multi_query(sql)
|
99
|
-
@conn.query(sql)
|
109
|
+
@pool.acquire { |conn| conn.query(sql) }
|
100
110
|
end
|
101
111
|
|
102
112
|
# Execute a single read query.
|
@@ -109,7 +119,7 @@ module Oedipus
|
|
109
119
|
#
|
110
120
|
# Note that SphinxQL does not support prepared statements.
|
111
121
|
def query(sql)
|
112
|
-
@conn.query(sql).first
|
122
|
+
@pool.acquire { |conn| conn.query(sql).first }
|
113
123
|
end
|
114
124
|
|
115
125
|
# Execute a non-read query.
|
@@ -122,7 +132,13 @@ module Oedipus
|
|
122
132
|
#
|
123
133
|
# Note that SphinxQL does not support prepared statements.
|
124
134
|
def execute(sql)
|
125
|
-
@conn.execute(sql)
|
135
|
+
@pool.acquire { |conn| conn.execute(sql) }
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
def assert_valid_pool
|
141
|
+
@pool.acquire { nil }
|
126
142
|
end
|
127
143
|
end
|
128
144
|
end
|
data/lib/oedipus/version.rb
CHANGED
data/lib/oedipus.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oedipus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-04-29 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &14417400 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *14417400
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake-compiler
|
27
|
-
requirement: &
|
27
|
+
requirement: &14717600 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *14717600
|
36
36
|
description: ! "== Sphinx 2 Comes to Ruby\n\nOedipus brings full support for Sphinx
|
37
37
|
2 to Ruby:\n\n - real-time indexes (insert, replace, update, delete)\n - faceted
|
38
38
|
search (variations on a base query)\n - multi-queries (multiple queries executed
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- lib/oedipus/comparison/outside.rb
|
71
71
|
- lib/oedipus/comparison/shortcuts.rb
|
72
72
|
- lib/oedipus/connection.rb
|
73
|
+
- lib/oedipus/connection/pool.rb
|
73
74
|
- lib/oedipus/connection_error.rb
|
74
75
|
- lib/oedipus/index.rb
|
75
76
|
- lib/oedipus/query_builder.rb
|
@@ -108,7 +109,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
109
|
version: '0'
|
109
110
|
segments:
|
110
111
|
- 0
|
111
|
-
hash:
|
112
|
+
hash: 4166348847258820467
|
112
113
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
114
|
none: false
|
114
115
|
requirements:
|
@@ -117,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
118
|
version: '0'
|
118
119
|
segments:
|
119
120
|
- 0
|
120
|
-
hash:
|
121
|
+
hash: 4166348847258820467
|
121
122
|
requirements: []
|
122
123
|
rubyforge_project: oedipus
|
123
124
|
rubygems_version: 1.8.11
|