oldmoe-neverblock-pg 0.1.0
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/README +8 -0
- data/lib/never_block/db/fibered_postgres_connection.rb +81 -0
- data/lib/never_block/db/pooled_fibered_postgres_connection.rb +44 -0
- data/lib/neverblock-pg.rb +4 -0
- data/neverblock-pg.gemspec +23 -0
- data/test/test.rb +101 -0
- metadata +77 -0
data/README
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
== NeverBlock PG
|
2
|
+
|
3
|
+
A fibered, evented PostgreSQL database driver. Blocking queries running in fibers will run in async mode and yield the fiber.
|
4
|
+
|
5
|
+
The connection socket can be accessed for future notifications. This driver can be used together with other NeverBlock components to provide a full non-blocking stack for Ruby applications.
|
6
|
+
|
7
|
+
=== License
|
8
|
+
Ruby License, http://www.ruby-lang.org/en/LICENSE.txt.
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'pg'
|
2
|
+
|
3
|
+
module NeverBlock
|
4
|
+
|
5
|
+
module DB
|
6
|
+
|
7
|
+
class FiberedPostgresConnection < PGconn
|
8
|
+
|
9
|
+
attr_reader :fd, :io
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
super(*args)
|
13
|
+
@fd = socket
|
14
|
+
@io = IO.new(socket)
|
15
|
+
setnonblocking(true)
|
16
|
+
end
|
17
|
+
|
18
|
+
#Assuming the use of NeverBlock fiber extensions and that the exec is run in
|
19
|
+
#the context of a fiber
|
20
|
+
def exec(sql)
|
21
|
+
if Fiber.respond_to? :current and Fiber.current[:neverblock]
|
22
|
+
self.send_query sql
|
23
|
+
@fiber = Fiber.current
|
24
|
+
Fiber.yield
|
25
|
+
else
|
26
|
+
super(sql)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def register_with_event_loop(loop)
|
32
|
+
if loop == :em
|
33
|
+
unless EM.respond_to?(:notify_for_read)
|
34
|
+
puts "invalide EM version, please download the modified gem from: (TBA) "
|
35
|
+
exit
|
36
|
+
end
|
37
|
+
if EM.reactor_running?
|
38
|
+
EM::attach(@io,EMConnectionHandler,self)
|
39
|
+
else
|
40
|
+
raise "REACTOR NOT RUNNING YA ZALAMA"
|
41
|
+
end
|
42
|
+
elsif loop.class.name == "REV::Loop"
|
43
|
+
loop.attach(RevConnectionHandler.new(socket))
|
44
|
+
else
|
45
|
+
raise "di zebala ya gahel"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
#The callback
|
50
|
+
def process_command
|
51
|
+
# make sure all commands are sent
|
52
|
+
# before attempting to read
|
53
|
+
return unless self.flush
|
54
|
+
self.consume_input
|
55
|
+
unless is_busy
|
56
|
+
res, data = 0, []
|
57
|
+
while res != nil
|
58
|
+
res = self.get_result
|
59
|
+
data << res unless res.nil?
|
60
|
+
end
|
61
|
+
#let the fiber continue its work
|
62
|
+
@fiber.resume(data.last)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end #FiberedPostgresConnection
|
67
|
+
|
68
|
+
module EMConnectionHandler
|
69
|
+
def initialize connection
|
70
|
+
@connection = connection
|
71
|
+
end
|
72
|
+
def notify_readable
|
73
|
+
@connection.process_command
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end #DB
|
78
|
+
|
79
|
+
end #NeverBlock
|
80
|
+
|
81
|
+
NeverBlock::DB::FPGconn = NeverBlock::DB::FiberedPostgresConnection
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module NeverBlock
|
2
|
+
module DB
|
3
|
+
class PooledFiberedPostgresConnection
|
4
|
+
|
5
|
+
def initialize(conn_params, size)
|
6
|
+
@pool = NB::Pool::FiberedConnectionPool.new(:size=>size, :eager=>true) do
|
7
|
+
conn = NB::DB::FPGconn.new(conn_params)
|
8
|
+
conn.register_with_event_loop(:em)
|
9
|
+
conn
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def exec(query)
|
14
|
+
@pool.hold do |conn|
|
15
|
+
conn.exec(query)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def begin_db_transaction
|
20
|
+
@pool.hold(true) do |conn|
|
21
|
+
conn.exec("begin")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def rollback_db_transaction
|
26
|
+
@pool.hold do |conn|
|
27
|
+
conn.exec("rollback")
|
28
|
+
release(Fiber.current,conn)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def commit_db_transaction
|
33
|
+
@pool.hold do |conn|
|
34
|
+
conn.exec("commit")
|
35
|
+
release(Fiber.current,conn)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
NB::DB::PFPGconn = NeverBlock::DB::FiberedPostgresConnection
|
44
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "neverblock-pg"
|
3
|
+
s.version = "0.1.0"
|
4
|
+
s.date = "2008-08-13"
|
5
|
+
s.summary = "Fibered PostgreSQL connection"
|
6
|
+
s.email = "oldmoe@gmail.com"
|
7
|
+
s.homepage = "http://github.com/oldmoe/neverblock-pg"
|
8
|
+
s.description = "Fibered PostgreSQL connection."
|
9
|
+
s.has_rdoc = true
|
10
|
+
s.authors = ["Muhammad A. Ali", "Ahmed Sobhi"]
|
11
|
+
s.files = [
|
12
|
+
"neverblock-pg.gemspec",
|
13
|
+
"README",
|
14
|
+
"test/test.rb",
|
15
|
+
"lib/neverblock-pg.rb",
|
16
|
+
"lib/never_block/db/fibered_postgres_connection.rb",
|
17
|
+
"lib/never_block/db/pooled_fibered_postgres_connection.rb"]
|
18
|
+
s.rdoc_options = ["--main", "README"]
|
19
|
+
s.extra_rdoc_files = ["README"]
|
20
|
+
s.add_dependency("neverblock")
|
21
|
+
s.add_dependency("pg")
|
22
|
+
end
|
23
|
+
|
data/test/test.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'neverblock'
|
2
|
+
require 'neverblock-pg'
|
3
|
+
|
4
|
+
$fpool = NB::Pool::FiberPool.new(24)
|
5
|
+
|
6
|
+
$long_count = ARGV[0].to_i
|
7
|
+
$freq = ARGV[1].to_i
|
8
|
+
$done = false
|
9
|
+
|
10
|
+
$connections = {}
|
11
|
+
$sockets = []
|
12
|
+
$cpool = NB::Pool::FiberedConnectionPool.new(:size=>10, :eager=>true) {
|
13
|
+
conn = NB::DB::FPGconn.new({:host=>'localhost',:user=>'postgres',:dbname=>'evented'})
|
14
|
+
$sockets << socket = IO.new(conn.socket)
|
15
|
+
$connections[socket] = conn
|
16
|
+
}
|
17
|
+
|
18
|
+
def $cpool.exec(sql)
|
19
|
+
hold do |conn|
|
20
|
+
conn.exec(sql)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def $cpool.[](sql)
|
25
|
+
self.exec(sql)
|
26
|
+
end
|
27
|
+
|
28
|
+
def $cpool.begin_db_transaction
|
29
|
+
hold(true) do |conn|
|
30
|
+
conn.exec("begin")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
def $cpool.rollback_db_transaction
|
34
|
+
hold do |conn|
|
35
|
+
conn.exec("rollback")
|
36
|
+
release(Fiber.current,conn)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
def $cpool.commit_db_transaction
|
40
|
+
hold do |conn|
|
41
|
+
conn.exec("commit")
|
42
|
+
release(Fiber.current,conn)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
$long_query = "select sleep(1)"
|
47
|
+
$short_query = "select 1"
|
48
|
+
|
49
|
+
def run_blocking
|
50
|
+
t = Time.now
|
51
|
+
$long_count.times do |i|
|
52
|
+
$cpool[$long_query]
|
53
|
+
$freq.times do |j|
|
54
|
+
$cpool[$short_query].each{|r|r}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
Time.now - t
|
58
|
+
end
|
59
|
+
print "finished blocking queries in : "
|
60
|
+
puts $b_time = run_blocking
|
61
|
+
|
62
|
+
def run_evented
|
63
|
+
$count = 0
|
64
|
+
$count_long = 0
|
65
|
+
$finished = 0
|
66
|
+
$long_count.times do |i|
|
67
|
+
$fpool.spawn do
|
68
|
+
$cpool[$long_query].each{|r|r}
|
69
|
+
$finished = $finished + 1
|
70
|
+
if $finished == ($long_count * ($freq+1))
|
71
|
+
puts ($e_l_time = Time.now - $t)
|
72
|
+
puts "advantage = #{(100 - ( $e_l_time / $b_time ) * 100).to_i}%"
|
73
|
+
stop_loop
|
74
|
+
end
|
75
|
+
end
|
76
|
+
$freq.times do |j|
|
77
|
+
$fpool.spawn do
|
78
|
+
$cpool[$short_query].each{|r|r}
|
79
|
+
$finished = $finished + 1
|
80
|
+
if $finished == ($long_count * ($freq+1))
|
81
|
+
puts ($e_l_time = Time.now - $t)
|
82
|
+
puts "advantage = #{(100 - ( $e_l_time / $b_time ) * 100).to_i}%"
|
83
|
+
stop_loop
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def stop_loop
|
91
|
+
$done = true
|
92
|
+
end
|
93
|
+
|
94
|
+
$t = Time.now
|
95
|
+
print "finished evented queries in : "
|
96
|
+
run_evented
|
97
|
+
loop do
|
98
|
+
res = select($sockets,nil,nil,nil)
|
99
|
+
res.first.each{ |s|$connections[s].process_command } if res
|
100
|
+
break if $done
|
101
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oldmoe-neverblock-pg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Muhammad A. Ali
|
8
|
+
- Ahmed Sobhi
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2008-08-13 00:00:00 -07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: neverblock
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: pg
|
27
|
+
version_requirement:
|
28
|
+
version_requirements: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: "0"
|
33
|
+
version:
|
34
|
+
description: Fibered PostgreSQL connection.
|
35
|
+
email: oldmoe@gmail.com
|
36
|
+
executables: []
|
37
|
+
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files:
|
41
|
+
- README
|
42
|
+
files:
|
43
|
+
- neverblock-pg.gemspec
|
44
|
+
- README
|
45
|
+
- test/test.rb
|
46
|
+
- lib/neverblock-pg.rb
|
47
|
+
- lib/never_block/db/fibered_postgres_connection.rb
|
48
|
+
- lib/never_block/db/pooled_fibered_postgres_connection.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/oldmoe/neverblock-pg
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options:
|
53
|
+
- --main
|
54
|
+
- README
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
version:
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.2.0
|
73
|
+
signing_key:
|
74
|
+
specification_version: 2
|
75
|
+
summary: Fibered PostgreSQL connection
|
76
|
+
test_files: []
|
77
|
+
|