oldmoe-neverblock-pg 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,4 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__))
2
+
3
+ require 'never_block/db/fibered_postgres_connection'
4
+ require 'never_block/db/pooled_fibered_postgres_connection'
@@ -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
+