neverblock 0.1.6.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,106 @@
1
+ $:.unshift File.expand_path('..')
2
+ require 'lib/neverblock'
3
+
4
+ class MockConnection; end
5
+
6
+ describe NB::Pool::FiberedConnectionPool do
7
+ before(:each) do
8
+ @pool = NB::Pool::FiberedConnectionPool.new(:size => 10) do
9
+ MockConnection.new
10
+ end
11
+ end
12
+
13
+ it "should create all connections lazily by default" do
14
+ @pool.instance_variable_get(:@connections).length.should == 0
15
+ @pool.instance_variable_get(:@busy_connections).length.should == 0
16
+ end
17
+
18
+ it "should create all connections eagerly if specified" do
19
+ @pool = NB::Pool::FiberedConnectionPool.new(:size => 10, :eager => true) do
20
+ MockConnection.new
21
+ end
22
+ @pool.instance_variable_get(:@connections).length.should == 10
23
+ @pool.instance_variable_get(:@busy_connections).length.should == 0
24
+ end
25
+
26
+ it "should create and yield a connection if :size not reached" do
27
+ @pool.instance_variable_get(:@connections).length.should == 0
28
+ @pool.instance_variable_get(:@busy_connections).length.should == 0
29
+
30
+ @pool.hold {|conn| conn.should be_instance_of(MockConnection)}
31
+
32
+ @pool.instance_variable_get(:@connections).length.should == 1
33
+ @pool.instance_variable_get(:@busy_connections).length.should == 0
34
+ end
35
+
36
+ it "should create connections up to :size and queue other requests" do
37
+ # prepate the fiber pool
38
+ fpool = NB::Pool::FiberPool.new(15)
39
+ fibers = []; fpool.fibers.each {|f| fibers << f}
40
+ progress = Array.new(15, false)
41
+
42
+ # send 15 requests to the connection pool (of size 10)
43
+ 10.times do |i|
44
+ fpool.spawn do
45
+ @pool.hold do |conn|
46
+ Fiber.yield
47
+ progress[i] = Fiber.current #mark task finished
48
+ end
49
+ end
50
+ end
51
+ (10..14).each do |i|
52
+ fpool.spawn do
53
+ @pool.hold do |conn|
54
+ progress[i] = Fiber.current #mark task finished
55
+ end
56
+ end
57
+ end
58
+
59
+ # 10 requests should be in progress and 5 should be queued
60
+ @pool.instance_variable_get(:@connections).length.should == 0
61
+ @pool.instance_variable_get(:@busy_connections).length.should == 10
62
+ @pool.instance_variable_get(:@queue).length.should == 5
63
+
64
+ #resume first request which will finish it and will also handle the
65
+ #queued requests
66
+ fibers[0].resume
67
+ [0,*10..14].each {|i| fibers[i].should == progress[i]}
68
+ [*1..9].each do |i|
69
+ progress[i].should == false
70
+ fibers[i].resume
71
+ progress[i].should == fibers[i]
72
+ end
73
+ end
74
+
75
+ it "should use the same connection in a transaction" do
76
+ #make sure there are more than one connection in the pool
77
+ @pool = NB::Pool::FiberedConnectionPool.new(:size => 10, :eager => true) do
78
+ MockConnection.new
79
+ end
80
+ fpool = NB::Pool::FiberPool.new(12)
81
+ fibers = []; fpool.fibers.each {|f| fibers << f}
82
+ t_conn = nil
83
+ fpool.spawn do
84
+ #announce the beginning of a transaction
85
+ @pool.hold(true) {|conn| t_conn = conn}
86
+
87
+ #another call to hold should get the same transaction's connection
88
+ @pool.hold {|conn| t_conn.should == conn}
89
+
90
+ #release the transaction connection
91
+ @pool.hold do |conn|
92
+ t_conn.should == conn
93
+ @pool.release(Fiber.current, conn)
94
+ end
95
+
96
+ #will now get a connection other than the transation's one (since there
97
+ #are many connections. If there was only one then it would have been
98
+ #returned anyways)
99
+ @pool.hold {|conn| t_conn.should_not == conn}
100
+ end
101
+ end
102
+
103
+ after(:each) do
104
+ @pool = nil
105
+ end
106
+ end
@@ -0,0 +1,12 @@
1
+ $:.unshift File.expand_path('..')
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'spec/rake/spectask'
6
+
7
+ desc "Run all specs"
8
+
9
+ Spec::Rake::SpecTask.new do |t|
10
+ t.spec_files = FileList['spec/*_spec.rb']
11
+ t.spec_opts = ["--format specdoc"]
12
+ end
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'neverblock'
3
+ require 'neverblock-mysql'
4
+
5
+ class Mysql
6
+ attr_accessor :fiber
7
+ end
8
+
9
+ @count = 100
10
+ @connections = {}
11
+ @fpool = NB::Pool::FiberPool.new(@count)
12
+ @cpool = NB::Pool::FiberedConnectionPool.new(size:@count, eager:true) do
13
+ c = NB::DB::FiberedMysqlConnection.real_connect('localhost','root',nil)
14
+ @connections[c.io] = c
15
+ c
16
+ end
17
+
18
+ @break = false
19
+ @done = 0
20
+ @t = Time.now
21
+ @count.times do
22
+ @fpool.spawn do
23
+ @cpool.hold do |conn|
24
+ conn.query('select sleep(1) as sleep').each{|r|p r}
25
+ @done = @done + 1
26
+ puts "done in #{Time.now - @t}" if @done == @count
27
+ end
28
+ end
29
+ end
30
+ @sockets = @connections.keys
31
+ loop do
32
+ res = select(@sockets,nil,nil,nil)
33
+ if res
34
+ res.first.each{|s|@connections[s].resume_command}
35
+ end
36
+ end
@@ -0,0 +1,102 @@
1
+ require 'rubygems'
2
+ require 'neverblock'
3
+ require 'neverblock-pg'
4
+
5
+ $fpool = NB::Pool::FiberPool.new(50)
6
+
7
+ $long_count = ARGV[0].to_i
8
+ $freq = ARGV[1].to_i
9
+ $done = false
10
+
11
+ $connections = {}
12
+ $sockets = []
13
+ $cpool = NB::Pool::FiberedConnectionPool.new(:size=>10, :eager=>true) {
14
+ conn = NB::DB::FPGconn.new({:host=>'localhost',:user=>'postgres',:dbname=>'evented'})
15
+ $sockets << socket = IO.new(conn.socket)
16
+ $connections[socket] = conn
17
+ }
18
+
19
+ def $cpool.exec(sql)
20
+ hold do |conn|
21
+ conn.exec(sql)
22
+ end
23
+ end
24
+
25
+ def $cpool.[](sql)
26
+ self.exec(sql)
27
+ end
28
+
29
+ def $cpool.begin_db_transaction
30
+ hold(true) do |conn|
31
+ conn.exec("begin")
32
+ end
33
+ end
34
+ def $cpool.rollback_db_transaction
35
+ hold do |conn|
36
+ conn.exec("rollback")
37
+ release(Fiber.current,conn)
38
+ end
39
+ end
40
+ def $cpool.commit_db_transaction
41
+ hold do |conn|
42
+ conn.exec("commit")
43
+ release(Fiber.current,conn)
44
+ end
45
+ end
46
+
47
+ $long_query = "select sleep(1)"
48
+ $short_query = "select 1"
49
+
50
+ def run_blocking
51
+ t = Time.now
52
+ $long_count.times do |i|
53
+ $cpool[$long_query]
54
+ $freq.times do |j|
55
+ $cpool[$short_query].each{|r|r}
56
+ end
57
+ end
58
+ Time.now - t
59
+ end
60
+ print "finished blocking queries in : "
61
+ puts $b_time = run_blocking
62
+
63
+ def run_evented
64
+ $count = 0
65
+ $count_long = 0
66
+ $finished = 0
67
+ $long_count.times do |i|
68
+ $fpool.spawn do
69
+ $cpool[$long_query].each{|r|r}
70
+ $finished = $finished + 1
71
+ if $finished == ($long_count * ($freq+1))
72
+ puts ($e_l_time = Time.now - $t)
73
+ puts "advantage = #{(100 - ( $e_l_time / $b_time ) * 100).to_i}%"
74
+ stop_loop
75
+ end
76
+ end
77
+ $freq.times do |j|
78
+ $fpool.spawn do
79
+ $cpool[$short_query].each{|r|r}
80
+ $finished = $finished + 1
81
+ if $finished == ($long_count * ($freq+1))
82
+ puts ($e_l_time = Time.now - $t)
83
+ puts "advantage = #{(100 - ( $e_l_time / $b_time ) * 100).to_i}%"
84
+ stop_loop
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ def stop_loop
92
+ $done = true
93
+ end
94
+
95
+ $t = Time.now
96
+ print "finished evented queries in : "
97
+ run_evented
98
+ loop do
99
+ res = select($sockets,nil,nil,nil)
100
+ res.first.each{ |s|$connections[s].resume_command } if res
101
+ break if $done
102
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: neverblock
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.6.2
5
+ platform: ruby
6
+ authors:
7
+ - Muhammad A. Ali
8
+ - Ahmed Sobhi
9
+ - Osama Brekaa
10
+ - Nicholas Silva
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+
15
+ date: 2010-02-03 00:00:00 -05:00
16
+ default_executable:
17
+ dependencies:
18
+ - !ruby/object:Gem::Dependency
19
+ name: eventmachine
20
+ type: :runtime
21
+ version_requirement:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.12.2
27
+ version:
28
+ description: NeverBlock is a collection of classes and modules that help you write evented non-blocking applications in a seemingly blocking mannner.
29
+ email: conickal@gmail.com
30
+ executables: []
31
+
32
+ extensions: []
33
+
34
+ extra_rdoc_files:
35
+ - README
36
+ files:
37
+ - README
38
+ - Rakefile
39
+ - VERSION
40
+ - lib/active_record/connection_adapters/neverblock_mysql_adapter.rb
41
+ - lib/active_record/connection_adapters/neverblock_postgresql_adapter.rb
42
+ - lib/never_block.rb
43
+ - lib/never_block/db/fibered_db_connection.rb
44
+ - lib/never_block/db/fibered_mysql_connection.rb
45
+ - lib/never_block/db/fibered_postgres_connection.rb
46
+ - lib/never_block/db/pooled_db_connection.rb
47
+ - lib/never_block/extensions/fiber_extensions.rb
48
+ - lib/never_block/frameworks/activerecord.rb
49
+ - lib/never_block/frameworks/rails.rb
50
+ - lib/never_block/pool/fiber_pool.rb
51
+ - lib/never_block/pool/fibered_connection_pool.rb
52
+ - lib/never_block/servers/mongrel.rb
53
+ - lib/never_block/servers/thin.rb
54
+ - lib/neverblock-mysql.rb
55
+ - lib/neverblock-pg.rb
56
+ - lib/neverblock.rb
57
+ - neverblock.gemspec
58
+ - spec/fiber_extensions_spec.rb
59
+ - spec/fiber_pool_spec.rb
60
+ - spec/fibered_connection_pool_spec.rb
61
+ - tasks/spec.rake
62
+ - test/test_mysql.rb
63
+ - test/test_pg.rb
64
+ has_rdoc: true
65
+ homepage: http://github.com/conickal/neverblock
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options:
70
+ - --charset=UTF-8
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ requirements: []
86
+
87
+ rubyforge_project:
88
+ rubygems_version: 1.3.5
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Utilities for non-blocking stack components
92
+ test_files:
93
+ - spec/fiber_extensions_spec.rb
94
+ - spec/fiber_pool_spec.rb
95
+ - spec/fibered_connection_pool_spec.rb
96
+ - test/test_mysql.rb
97
+ - test/test_pg.rb