fiber_connection_pool 0.2.2 → 0.2.3
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.
- checksums.yaml +7 -0
- data/examples/goliath_server_em_mongo/Gemfile +6 -0
- data/examples/goliath_server_em_mongo/config/main.rb +8 -0
- data/examples/goliath_server_em_mongo/main.rb +13 -0
- data/examples/goliath_server_mongo/Gemfile +5 -0
- data/examples/goliath_server_mongo/config/main.rb +10 -0
- data/examples/goliath_server_mongo/main.rb +13 -0
- data/examples/goliath_server_mongo/mongo-em-patch.rb +85 -0
- data/examples/reel_server_mongo/Gemfile +8 -0
- data/examples/reel_server_mongo/main.rb +67 -0
- data/lib/fiber_connection_pool.rb +3 -3
- data/test/fiber_connection_pool_test.rb +1 -1
- metadata +24 -20
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 340c349ed71fd516c16b2ec7ff01b6de4fb65072
|
4
|
+
data.tar.gz: 31d1a2a20a195afa721c39ee2c8a65171fc0f8a2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 23daf95d4cb681737c91c94172503be106ea0f518ab26f140025c840367fc92abcc922089a46cc3e5c6844f87458da0a03e4f4dc0835d9defadbf3e987e2a8db
|
7
|
+
data.tar.gz: 269f02b50cda24eb6a0e23e683ee74060d4c57de74ed1e3827349c01872df0e89e802211c256fb152714e7ccb6a50dbedc67a237c9e154dfb5b6326ec848a0be
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'goliath'
|
2
|
+
require 'fiber'
|
3
|
+
|
4
|
+
class Main < Goliath::API
|
5
|
+
|
6
|
+
def response(env)
|
7
|
+
print '.'
|
8
|
+
res = db.collection('bogus').find( :$where => "sleep(2000)" )
|
9
|
+
puts "Done #{Thread.current.to_s}, #{Fiber.current.to_s} res:#{res.inspect}"
|
10
|
+
[200,{"Content-Type" => "text/html"},"hello, world! #{Time.now.strftime('%T')}"]
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'goliath'
|
2
|
+
require 'fiber'
|
3
|
+
|
4
|
+
class Main < Goliath::API
|
5
|
+
|
6
|
+
def response(env)
|
7
|
+
print '.'
|
8
|
+
res = db.collection('bogus').find( :$where => "sleep(2000)" ).count
|
9
|
+
puts "Done #{Thread.current.to_s}, #{Fiber.current.to_s} res:#{res.inspect}"
|
10
|
+
[200,{"Content-Type" => "text/html"},"hello, world! #{Time.now.strftime('%T')}"]
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'fiber'
|
2
|
+
|
3
|
+
class EventMachine::Synchrony::MongoTimeoutHandler
|
4
|
+
def self.timeout(op_timeout, ex_class, &block)
|
5
|
+
f = Fiber.current
|
6
|
+
timer = EM::Timer.new(op_timeout) { f.resume(nil) }
|
7
|
+
res = block.call
|
8
|
+
timer.cancel
|
9
|
+
res
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Mongo::Connection
|
14
|
+
Mutex = ::EventMachine::Synchrony::Thread::Mutex
|
15
|
+
end
|
16
|
+
|
17
|
+
class Mongo::MongoClient
|
18
|
+
ConditionVariable = ::EventMachine::Synchrony::Thread::ConditionVariable
|
19
|
+
Timeout = ::EventMachine::Synchrony::MongoTimeoutHandler
|
20
|
+
end
|
21
|
+
|
22
|
+
class Mongo::Pool
|
23
|
+
ConditionVariable = ::EventMachine::Synchrony::Thread::ConditionVariable
|
24
|
+
Mutex = ::EventMachine::Synchrony::Thread::Mutex
|
25
|
+
end
|
26
|
+
|
27
|
+
class Mongo::Node
|
28
|
+
Mutex = ::EventMachine::Synchrony::Thread::Mutex
|
29
|
+
Timeout = ::EventMachine::Synchrony::MongoTimeoutHandler
|
30
|
+
end
|
31
|
+
|
32
|
+
class Mongo::TCPSocket
|
33
|
+
Timeout = ::EventMachine::Synchrony::MongoTimeoutHandler
|
34
|
+
end
|
35
|
+
|
36
|
+
class Mongo::SSLSocket
|
37
|
+
Timeout = ::EventMachine::Synchrony::MongoTimeoutHandler
|
38
|
+
end
|
39
|
+
|
40
|
+
class Mongo::MongoReplicaSetClient
|
41
|
+
Mutex = ::EventMachine::Synchrony::Thread::Mutex
|
42
|
+
end
|
43
|
+
|
44
|
+
class Mongo::MongoShardedClient
|
45
|
+
Mutex = ::EventMachine::Synchrony::Thread::Mutex
|
46
|
+
end
|
47
|
+
|
48
|
+
class Mongo::PoolManager
|
49
|
+
Mutex = ::EventMachine::Synchrony::Thread::Mutex
|
50
|
+
end
|
51
|
+
|
52
|
+
class Mongo::TCPSocket
|
53
|
+
|
54
|
+
def initialize(host, port, op_timeout=nil, connect_timeout=nil, opts={})
|
55
|
+
@op_timeout = op_timeout || 30
|
56
|
+
@connect_timeout = connect_timeout || 30
|
57
|
+
@pid = Process.pid
|
58
|
+
|
59
|
+
# TODO: Prefer ipv6 if server is ipv6 enabled
|
60
|
+
@address = Socket.getaddrinfo(host, nil, Socket::AF_INET).first[3]
|
61
|
+
@port = port
|
62
|
+
|
63
|
+
@socket = nil
|
64
|
+
connect
|
65
|
+
end
|
66
|
+
|
67
|
+
def connect
|
68
|
+
::EventMachine::Synchrony::MongoTimeoutHandler.timeout(@connect_timeout, Mongo::ConnectionTimeoutError) do
|
69
|
+
@socket = EM::Synchrony::TCPSocket.new(@address, @port)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def send(data)
|
74
|
+
raise SocketError, 'Not connected yet' if not @socket
|
75
|
+
@socket.write(data)
|
76
|
+
end
|
77
|
+
|
78
|
+
def read(maxlen, buffer)
|
79
|
+
raise SocketError, 'Not connected yet' if not @socket
|
80
|
+
::EventMachine::Synchrony::MongoTimeoutHandler.timeout(@op_timeout, Mongo::OperationTimeout) do
|
81
|
+
@socket.read(maxlen, buffer)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'celluloid', github: 'celluloid/celluloid', branch: 'master'
|
4
|
+
gem 'celluloid-io', github: 'celluloid/celluloid-io', branch: 'master'
|
5
|
+
gem 'reel', github: 'celluloid/reel', branch: 'master'
|
6
|
+
gem 'mongo'
|
7
|
+
gem 'fiber_connection_pool'
|
8
|
+
gem 'em-synchrony'
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'reel'
|
2
|
+
require 'mongo'
|
3
|
+
require 'fiber'
|
4
|
+
require 'fiber_connection_pool'
|
5
|
+
require 'celluloid/autostart'
|
6
|
+
|
7
|
+
class Dispatcher
|
8
|
+
include Celluloid::IO
|
9
|
+
|
10
|
+
def initialize(opts = {})
|
11
|
+
@db_pool_size = opts[:db_pool_size] || 5
|
12
|
+
@pool = FiberConnectionPool.new(:size => @db_pool_size) do
|
13
|
+
Mongo::MongoClient.new.db('bogusdb')
|
14
|
+
end
|
15
|
+
puts "DB Pool of size #{@db_pool_size} ready..."
|
16
|
+
end
|
17
|
+
|
18
|
+
def dispatch(request)
|
19
|
+
print '.'
|
20
|
+
id = @pool.collection("bogus").find({ :$where => 'sleep(2000)' }).count
|
21
|
+
puts "Done #{Thread.current.to_s}, #{Fiber.current.to_s}"
|
22
|
+
request.respond :ok, "hello, world! #{Time.now.strftime('%T')}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
class DispatcherPool
|
28
|
+
|
29
|
+
def initialize(opts = {})
|
30
|
+
@size = opts[:size] || 1
|
31
|
+
@dispatchers = []
|
32
|
+
@size.times{ |i| @dispatchers << "dispatcher_#{i}".to_sym }
|
33
|
+
@dispatchers.each{ |d| Dispatcher.supervise_as d }
|
34
|
+
@next_dispatcher = 0
|
35
|
+
puts "Pool of #{@size} dispatchers ready."
|
36
|
+
end
|
37
|
+
|
38
|
+
def dispatch(request)
|
39
|
+
d = @next_dispatcher
|
40
|
+
@next_dispatcher += 1
|
41
|
+
@next_dispatcher = 0 if @next_dispatcher >= @dispatchers.count
|
42
|
+
Celluloid::Actor[@dispatchers[d]].dispatch(request)
|
43
|
+
rescue => ex
|
44
|
+
puts "Someone died: #{ex}"
|
45
|
+
request.respond :internal_server_error, "Someone died"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
class MyServer < Reel::Server
|
52
|
+
|
53
|
+
def initialize(host = "127.0.0.1", port = 3000)
|
54
|
+
super(host, port, &method(:on_connection))
|
55
|
+
@dispatcher = DispatcherPool.new
|
56
|
+
puts "Listening on #{host}:#{port}..."
|
57
|
+
end
|
58
|
+
|
59
|
+
def on_connection(connection)
|
60
|
+
while request = connection.request
|
61
|
+
@dispatcher.dispatch(request)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
MyServer.run
|
@@ -2,7 +2,7 @@ require 'fiber'
|
|
2
2
|
require_relative 'fiber_connection_pool/exceptions'
|
3
3
|
|
4
4
|
class FiberConnectionPool
|
5
|
-
VERSION = '0.2.
|
5
|
+
VERSION = '0.2.3'
|
6
6
|
|
7
7
|
RESERVED_TTL_SECS = 30 # reserved cleanup trigger
|
8
8
|
SAVED_DATA_TTL_SECS = 30 # saved_data cleanup trigger
|
@@ -127,7 +127,7 @@ class FiberConnectionPool
|
|
127
127
|
new_conn = yield bad_conn
|
128
128
|
@available.reject!{ |v| v == bad_conn }
|
129
129
|
@reserved.reject!{ |k,v| v == bad_conn }
|
130
|
-
@available.
|
130
|
+
@available.unshift new_conn
|
131
131
|
# try to cleanup
|
132
132
|
begin
|
133
133
|
bad_conn.close
|
@@ -210,7 +210,7 @@ class FiberConnectionPool
|
|
210
210
|
# Also perform cleanup if TTL is past
|
211
211
|
#
|
212
212
|
def release(fiber)
|
213
|
-
@available.
|
213
|
+
@available.unshift @reserved.delete(fiber)
|
214
214
|
|
215
215
|
# try cleanup
|
216
216
|
reserved_cleanup if (Time.now - @last_reserved_cleanup) >= RESERVED_TTL_SECS
|
@@ -25,7 +25,7 @@ class TestFiberConnectionPool < Minitest::Test
|
|
25
25
|
# we should have visited 1 thread, 15 fibers and 1 instances
|
26
26
|
assert_equal 1, info[:threads].count
|
27
27
|
assert_equal 15, info[:fibers].count
|
28
|
-
assert_equal
|
28
|
+
assert_equal 5, info[:instances].count
|
29
29
|
end
|
30
30
|
|
31
31
|
def test_em_synchrony_behaviour
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fiber_connection_pool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.3
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Ruben Caro
|
@@ -10,43 +9,40 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date: 2013-09-
|
12
|
+
date: 2013-09-14 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: minitest
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
17
|
requirements:
|
20
|
-
- -
|
18
|
+
- - '>='
|
21
19
|
- !ruby/object:Gem::Version
|
22
20
|
version: '0'
|
23
21
|
type: :development
|
24
22
|
prerelease: false
|
25
23
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
24
|
requirements:
|
28
|
-
- -
|
25
|
+
- - '>='
|
29
26
|
- !ruby/object:Gem::Version
|
30
27
|
version: '0'
|
31
28
|
- !ruby/object:Gem::Dependency
|
32
29
|
name: rake
|
33
30
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
31
|
requirements:
|
36
|
-
- -
|
32
|
+
- - '>='
|
37
33
|
- !ruby/object:Gem::Version
|
38
34
|
version: '0'
|
39
35
|
type: :development
|
40
36
|
prerelease: false
|
41
37
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
38
|
requirements:
|
44
|
-
- -
|
39
|
+
- - '>='
|
45
40
|
- !ruby/object:Gem::Version
|
46
41
|
version: '0'
|
47
|
-
description:
|
48
|
-
|
49
|
-
|
42
|
+
description: |-
|
43
|
+
Fiber-based generic connection pool for Ruby, allowing
|
44
|
+
non-blocking IO behaviour on the same thread
|
45
|
+
as provided by EventMachine or Celluloid.
|
50
46
|
email:
|
51
47
|
- ruben.caro@lanuez.org
|
52
48
|
executables: []
|
@@ -63,8 +59,17 @@ files:
|
|
63
59
|
- examples/goliath_server/Gemfile
|
64
60
|
- examples/goliath_server/config/main.rb
|
65
61
|
- examples/goliath_server/main.rb
|
62
|
+
- examples/goliath_server_em_mongo/Gemfile
|
63
|
+
- examples/goliath_server_em_mongo/config/main.rb
|
64
|
+
- examples/goliath_server_em_mongo/main.rb
|
65
|
+
- examples/goliath_server_mongo/Gemfile
|
66
|
+
- examples/goliath_server_mongo/config/main.rb
|
67
|
+
- examples/goliath_server_mongo/main.rb
|
68
|
+
- examples/goliath_server_mongo/mongo-em-patch.rb
|
66
69
|
- examples/reel_server/Gemfile
|
67
70
|
- examples/reel_server/main.rb
|
71
|
+
- examples/reel_server_mongo/Gemfile
|
72
|
+
- examples/reel_server_mongo/main.rb
|
68
73
|
- fiber_connection_pool.gemspec
|
69
74
|
- lib/fiber_connection_pool.rb
|
70
75
|
- lib/fiber_connection_pool/exceptions.rb
|
@@ -73,27 +78,26 @@ files:
|
|
73
78
|
homepage: https://github.com/rubencaro/fiber_connection_pool
|
74
79
|
licenses:
|
75
80
|
- GPLv3
|
81
|
+
metadata: {}
|
76
82
|
post_install_message:
|
77
83
|
rdoc_options: []
|
78
84
|
require_paths:
|
79
85
|
- lib
|
80
86
|
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
87
|
requirements:
|
83
|
-
- -
|
88
|
+
- - '>='
|
84
89
|
- !ruby/object:Gem::Version
|
85
90
|
version: 1.9.2
|
86
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
-
none: false
|
88
92
|
requirements:
|
89
|
-
- -
|
93
|
+
- - '>='
|
90
94
|
- !ruby/object:Gem::Version
|
91
95
|
version: '0'
|
92
96
|
requirements: []
|
93
97
|
rubyforge_project:
|
94
|
-
rubygems_version:
|
98
|
+
rubygems_version: 2.0.6
|
95
99
|
signing_key:
|
96
|
-
specification_version:
|
100
|
+
specification_version: 4
|
97
101
|
summary: Fiber-based generic connection pool for Ruby
|
98
102
|
test_files:
|
99
103
|
- test/fiber_connection_pool_test.rb
|