oldmoe-neverblock 0.1.3 → 0.1.4

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.
@@ -37,7 +37,7 @@ class ActiveRecord::ConnectionAdapters::NeverBlockMysqlAdapter < ActiveRecord::C
37
37
  end
38
38
 
39
39
  def connect
40
- @connection = ::NB::DB::PooledFiberedMysqlConnection.new(@connection_options.shift) do
40
+ @connection = ::NB::DB::PooledDBConnection.new(@connection_options.shift) do
41
41
  conn = ::NB::DB::FMysql.init
42
42
  encoding = @config[:encoding]
43
43
  if encoding
@@ -28,47 +28,38 @@ class ActiveRecord::ConnectionAdapters::NeverBlockPostgreSQLAdapter < ActiveReco
28
28
  end
29
29
 
30
30
  def connect
31
- size = @connection_parameters.shift
32
- @connection = ::NB::DB::PooledFiberedPostgresConnection.new(@connection_parameters, size)
33
-
34
- PGconn.translate_results = false if PGconn.respond_to?(:translate_results=)
35
-
36
- # Ignore async_exec and async_query when using postgres-pr.
37
- @async = @config[:allow_concurrency] && @connection.respond_to?(:async_exec)
38
-
39
- # Use escape string syntax if available. We cannot do this lazily when encountering
40
- # the first string, because that could then break any transactions in progress.
41
- # See: http://www.postgresql.org/docs/current/static/runtime-config-compatible.html
42
- # If PostgreSQL doesn't know the standard_conforming_strings parameter then it doesn't
43
- # support escape string syntax. Don't override the inherited quoted_string_prefix.
44
- NB.neverblock(false) do
45
-
46
- @connection.begin_db_transaction
47
- if supports_standard_conforming_strings?
48
- self.class.instance_eval do
49
- define_method(:quoted_string_prefix) { 'E' }
50
- end
51
- end
52
-
53
- # Money type has a fixed precision of 10 in PostgreSQL 8.2 and below, and as of
54
- # PostgreSQL 8.3 it has a fixed precision of 19. PostgreSQLColumn.extract_precision
55
- # should know about this but can't detect it there, so deal with it here.
56
- money_precision = (postgresql_version >= 80300) ? 19 : 10
57
- ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn.module_eval(<<-end_eval)
58
- def extract_precision(sql_type)
59
- if sql_type =~ /^money$/
60
- #{money_precision}
61
- else
62
- super
31
+ @connection = ::NB::DB::PooledFiberedPostgresConnection.new(@connection_parameters.shift) do
32
+ conn = PGconn.connect(*@connection_parameters)
33
+ PGconn.translate_results = false if PGconn.respond_to?(:translate_results=)
34
+ # Ignore async_exec and async_query when using postgres-pr.
35
+ @async = @config[:allow_concurrency] && @connection.respond_to?(:async_exec)
36
+ # Use escape string syntax if available. We cannot do this lazily when encountering
37
+ # the first string, because that could then break any transactions in progress.
38
+ # See: http://www.postgresql.org/docs/current/static/runtime-config-compatible.html
39
+ # If PostgreSQL doesn't know the standard_conforming_strings parameter then it doesn't
40
+ # support escape string syntax. Don't override the inherited quoted_string_prefix.
41
+ NB.neverblock(false) do
42
+ if supports_standard_conforming_strings?
43
+ self.class.instance_eval do
44
+ define_method(:quoted_string_prefix) { 'E' }
63
45
  end
64
46
  end
65
- end_eval
66
-
67
- configure_connection
68
- @connection.commit_db_transaction
69
-
47
+ # Money type has a fixed precision of 10 in PostgreSQL 8.2 and below, and as of
48
+ # PostgreSQL 8.3 it has a fixed precision of 19. PostgreSQLColumn.extract_precision
49
+ # should know about this but can't detect it there, so deal with it here.
50
+ money_precision = (postgresql_version >= 80300) ? 19 : 10
51
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn.module_eval(<<-end_eval)
52
+ def extract_precision(sql_type)
53
+ if sql_type =~ /^money$/
54
+ #{money_precision}
55
+ else
56
+ super
57
+ end
58
+ end
59
+ end_eval
60
+ #configure_connection
61
+ end
70
62
  end
71
-
72
63
  end
73
64
 
74
65
  # Close then reopen the connection.
@@ -0,0 +1,57 @@
1
+ module NeverBlock
2
+ module DB
3
+ module FiberedDBConnection
4
+ # Attaches the connection socket to an event loop.
5
+ # Currently only supports EM, but Rev support will be
6
+ # completed soon.
7
+ def register_with_event_loop(loop)
8
+ @fd = socket
9
+ @io = IO.new(socket)
10
+ if loop == :em
11
+ if EM.reactor_running?
12
+ @em_connection = EM::attach(@io,EMConnectionHandler,self)
13
+ else
14
+ raise "REACTOR NOT RUNNING YA ZALAMA"
15
+ end
16
+ elsif loop.class.name == "REV::Loop"
17
+ loop.attach(RevConnectionHandler.new(@fd))
18
+ else
19
+ raise "could not register with the event loop"
20
+ end
21
+ @loop = loop
22
+ end
23
+
24
+ # Unattaches the connection socket from the event loop
25
+ def unregister_from_event_loop
26
+ if @loop == :em
27
+ @em_connection.detach
28
+ else
29
+ raise NotImplementedError.new("unregister_from_event_loop not implemented for #{@loop}")
30
+ end
31
+ end
32
+
33
+ # The callback, this is called whenever
34
+ # there is data available at the socket
35
+ def resume_command
36
+ #protection against being called several times
37
+ if @fiber
38
+ f = @fiber
39
+ @fiber = nil
40
+ f.resume
41
+ else
42
+ unregister_from_event_loop
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ module EMConnectionHandler
49
+ def initialize connection
50
+ @db_connection = connection
51
+ end
52
+ def notify_readable
53
+ @db_connection.resume_command
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,9 +1,9 @@
1
- require 'mysql'
1
+ require 'mysqlplus'
2
2
 
3
3
  module NeverBlock
4
4
 
5
5
  module DB
6
- # A modified postgres connection driver
6
+ # A modified mysql connection driver
7
7
  # builds on the original pg driver.
8
8
  # This driver is able to register the socket
9
9
  # at a certain backend (EM or Rev)
@@ -12,85 +12,48 @@ module NeverBlock
12
12
  # it will be done in async mode and the fiber
13
13
  # will yield
14
14
  class FiberedMysqlConnection < Mysql
15
- # needed to access the sockect by the event loop
16
- attr_reader :fd, :io
17
-
18
- # Creates a new mysql connection, sets it
19
- # to nonblocking and wraps the descriptor in an IO
20
- # object.
21
- def real_connect(*args)
22
- super(*args)
23
- @fd = socket
24
- @io = IO.new(socket)
25
- end
26
- #alias :real_connect :initialize
27
- #alias :connect :initialize
15
+
16
+ include FiberedDBConnection
28
17
 
29
18
  # Assuming the use of NeverBlock fiber extensions and that the exec is run in
30
19
  # the context of a fiber. One that have the value :neverblock set to true.
31
20
  # All neverblock IO classes check this value, setting it to false will force
32
21
  # the execution in a blocking way.
33
22
  def query(sql)
34
- if Fiber.respond_to? :current and Fiber.current[:neverblock]
35
- send_query sql
36
- @fiber = Fiber.current
37
- Fiber.yield
38
- else
39
- super(sql)
40
- end
41
- end
42
-
43
- # Attaches the connection socket to an event loop.
44
- # Currently only supports EM, but Rev support will be
45
- # completed soon.
46
- def register_with_event_loop(loop)
47
- if loop == :em
48
- unless EM.respond_to?(:attach)
49
- puts "invalide EM version, please download the modified gem from: (http://github.com/riham/eventmachine)"
50
- exit
23
+ begin
24
+ if Fiber.respond_to? :current and Fiber.current[:neverblock]
25
+ send_query sql
26
+ @fiber = Fiber.current
27
+ Fiber.yield
28
+ get_result
29
+ else
30
+ super(sql)
51
31
  end
52
- if EM.reactor_running?
53
- @em_connection = EM::attach(@io,EMConnectionHandler,self)
54
- else
55
- raise "REACTOR NOT RUNNING YA ZALAMA"
56
- end
57
- elsif loop.class.name == "REV::Loop"
58
- loop.attach(RevConnectionHandler.new(socket))
59
- else
60
- raise "could not register with the event loop"
61
- end
62
- @loop = loop
63
- end
64
-
65
- # Unattaches the connection socket from the event loop
66
- def unregister_from_event_loop
67
- if @loop == :em
68
- @em_connection.unattach(false)
69
- else
70
- raise NotImplementedError.new("unregister_from_event_loop not implemented for #{@loop}")
71
- end
32
+ rescue Exception => e
33
+ if error = ['not connected', 'gone away', 'Lost connection'].detect{|msg| e.message.include? msg}
34
+ stop
35
+ connect
36
+ end
37
+ raise e
38
+ end
72
39
  end
73
40
 
74
- # The callback, this is called whenever
75
- # there is data available at the socket
76
- def process_command
77
- @fiber.resume get_result
78
- end
41
+ alias :exec :query
79
42
 
80
- end #FiberedPostgresConnection
81
-
82
- # A connection handler for EM
83
- # More to follow.
84
- module EMConnectionHandler
85
- def initialize connection
86
- @connection = connection
43
+ # stop the connection and deattach from the event loop
44
+ def stop
45
+ unregister_from_event_loop
87
46
  end
88
- def notify_readable
89
- @connection.process_command
47
+
48
+ # reconnect and attach to the event loop
49
+ def connect
50
+ super
51
+ register_with_event_loop(@loop)
90
52
  end
91
- end
53
+
54
+ end #FiberedMySQLConnection
92
55
 
93
- end #DB
56
+ end #DB
94
57
 
95
58
  end #NeverBlock
96
59
 
@@ -3,6 +3,7 @@ require 'pg'
3
3
  module NeverBlock
4
4
 
5
5
  module DB
6
+
6
7
  # A modified postgres connection driver
7
8
  # builds on the original pg driver.
8
9
  # This driver is able to register the socket
@@ -12,95 +13,50 @@ module NeverBlock
12
13
  # it will be done in async mode and the fiber
13
14
  # will yield
14
15
  class FiberedPostgresConnection < PGconn
15
- # needed to access the sockect by the event loop
16
- attr_reader :fd, :io
17
-
18
- # Creates a new postgresql connection, sets it
19
- # to nonblocking and wraps the descriptor in an IO
20
- # object.
21
- def initialize(*args)
22
- super(*args)
23
- @fd = socket
24
- @io = IO.new(socket)
25
- #setnonblocking(true)
26
- end
27
-
16
+
17
+ include FiberedDBConnection
18
+
28
19
  # Assuming the use of NeverBlock fiber extensions and that the exec is run in
29
20
  # the context of a fiber. One that have the value :neverblock set to true.
30
21
  # All neverblock IO classes check this value, setting it to false will force
31
22
  # the execution in a blocking way.
32
23
  def exec(sql)
33
- if Fiber.respond_to? :current and Fiber.current[:neverblock]
34
- self.send_query sql
35
- @fiber = Fiber.current
36
- Fiber.yield
37
- else
38
- super(sql)
39
- end
40
- end
41
-
42
- # Attaches the connection socket to an event loop.
43
- # Currently only supports EM, but Rev support will be
44
- # completed soon.
45
- def register_with_event_loop(loop)
46
- if loop == :em
47
- unless EM.respond_to?(:attach)
48
- puts "invalide EM version, please download the modified gem from: (http://github.com/riham/eventmachine)"
49
- exit
24
+ begin
25
+ if Fiber.respond_to? :current and Fiber.current[:neverblock]
26
+ send_query sql
27
+ @fiber = Fiber.current
28
+ Fiber.yield
29
+ while is_busy
30
+ consume_input
31
+ Fiber.yield if is_busy
32
+ end
33
+ res, data = 0, []
34
+ while res != nil
35
+ res = self.get_result
36
+ data << res unless res.nil?
37
+ end
38
+ data.last
39
+ else
40
+ super(sql)
50
41
  end
51
- if EM.reactor_running?
52
- @em_connection = EM::attach(@io,EMConnectionHandler,self)
53
- else
54
- raise "REACTOR NOT RUNNING YA ZALAMA"
55
- end
56
- elsif loop.class.name == "REV::Loop"
57
- loop.attach(RevConnectionHandler.new(socket))
58
- else
59
- raise "could not register with the event loop"
60
- end
61
- @loop = loop
42
+ rescue Exception => e
43
+ reset if e.message.include? "not connected"
44
+ raise e
45
+ end
62
46
  end
63
47
 
64
- # Unattaches the connection socket from the event loop
65
- # As with register, EM is the only one supported for now
66
- def unregister_from_event_loop
67
- if @loop == :em
68
- @em_connection.unattach(false)
69
- else
70
- raise NotImplementedError.new("unregister_from_event_loop not implemented for #{@loop}")
71
- end
72
- end
48
+ alias :query :exec
73
49
 
74
- # The callback, this is called whenever
75
- # there is data available at the socket
76
- def process_command
77
- # make sure all commands are sent
78
- # before attempting to read
79
- #return unless self.flush
80
- self.consume_input
81
- unless is_busy
82
- res, data = 0, []
83
- while res != nil
84
- res = self.get_result
85
- data << res unless res.nil?
86
- end
87
- #let the fiber continue its work
88
- @fiber.resume(data.last)
89
- end
50
+ # reset the connection
51
+ # and reattach to the
52
+ # event loop
53
+ def reset
54
+ unregister_from_event_loop
55
+ super
56
+ register_with_event_loop(@loop)
90
57
  end
91
-
58
+
92
59
  end #FiberedPostgresConnection
93
-
94
- # A connection handler for EM
95
- # More to follow.
96
- module EMConnectionHandler
97
- def initialize connection
98
- @connection = connection
99
- end
100
- def notify_readable
101
- @connection.process_command
102
- end
103
- end
104
60
 
105
61
  end #DB
106
62
 
@@ -1,19 +1,15 @@
1
1
  module NeverBlock
2
2
  module DB
3
- # A pooled postgres connection class.
4
- # This class represents a proxy interface
5
- # to a connection pool of fibered postgresql
6
- # connections.
7
- class PooledFiberedMysqlConnection
8
-
9
- # Requires a hash or an array with connection parameters
3
+ # a proxy for pooled fibered connections
4
+ class PooledDBConnection
5
+ # Requires a block with connection parameters
10
6
  # and a pool size (defaults to 4)
11
7
  def initialize(size=4, &block)
12
8
  @pool = NB::Pool::FiberedConnectionPool.new(:size=>size, :eager=>true) do
13
9
  yield
14
10
  end
15
11
  end
16
-
12
+
17
13
  # A proxy for the connection's query method
18
14
  # quries the pool to get a connection first
19
15
  def query(query)
@@ -21,6 +17,8 @@ module NeverBlock
21
17
  conn.query(query)
22
18
  end
23
19
  end
20
+
21
+ alias :exec :query
24
22
 
25
23
  # This method must be called for transactions to work correctly.
26
24
  # One cannot just send "begin" as you never know which connection
@@ -51,7 +49,6 @@ module NeverBlock
51
49
  #close all connections and remove them from the event loop
52
50
  def close
53
51
  @pool.all_connections do |conn|
54
- conn.unregister_from_event_loop
55
52
  conn.close
56
53
  end
57
54
  end
@@ -68,10 +65,7 @@ module NeverBlock
68
65
  @pool.hold do |conn|
69
66
  conn.respond_to?(method)
70
67
  end
71
- end
72
-
68
+ end
73
69
  end
74
70
  end
75
71
  end
76
-
77
- NeverBlock::DB::PFMysql = NeverBlock::DB::PooledFiberedMysqlConnection
@@ -1,6 +1,4 @@
1
1
  require 'neverblock' unless defined?(NeverBlock)
2
- #require 'actionpack'
3
- #require 'action_controller'
4
2
 
5
3
  # Rails tries to protect dispatched actions
6
4
  # by wrapping them in a synchronized code
@@ -9,29 +7,59 @@ require 'neverblock' unless defined?(NeverBlock)
9
7
  # transform it (without it knowing) to
10
8
  # something more subtle
11
9
 
12
-
13
- =begin
14
- class ActionController::Dispatcher
15
-
16
- # let's show this guard who is
17
- # the man of the house
18
- @@guard = Object.new
19
-
20
- # now you synchronize
21
- def @@guard.synchronize(&block)
10
+ require 'thread'
11
+ # now you synchronize
12
+ class Mutex
13
+ def synchronize(&block)
22
14
  # now you don't!
23
15
  block.call
24
16
  end
25
17
  end
26
- =end
27
18
 
19
+ require 'action_controller'
20
+ class ActionController::Base
28
21
 
29
- require 'thread'
22
+ # Mark some actions to execute in a blocking manner overriding the default
23
+ # settings.
24
+ # Example:
25
+ # class UsersController < ApplicationController
26
+ # .
27
+ # allowblock :index
28
+ # .
29
+ # end
30
+ def self.allowblock(*actions)
31
+ actions.each do |action|
32
+ class_eval <<-"end_eval"
33
+ def allowblock_#{action}
34
+ status = Fiber.current[:neverblock]
35
+ Fiber.current[:neverblock] = false
36
+ yield
37
+ Fiber.current[:neverblock] = status
38
+ end
39
+ around_filter :allowblock_#{action}, :only => [:#{action}]
40
+ end_eval
41
+ end
42
+ end
30
43
 
31
- # now you synchronize
32
- class Mutex
33
- def synchronize(&block)
34
- # now you don't!
35
- block.call
44
+ # Mark some actions to execute in a non-blocking manner overriding the default
45
+ # settings.
46
+ # Example:
47
+ # class UsersController < ApplicationController
48
+ # .
49
+ # allowblock :index
50
+ # .
51
+ # end
52
+ def self.neverblock(*actions)
53
+ actions.each do |action|
54
+ class_eval <<-"end_eval"
55
+ def neverblock_#{action}
56
+ status = Fiber.current[:neverblock]
57
+ Fiber.current[:neverblock] = true
58
+ yield
59
+ Fiber.current[:neverblock] = status
60
+ end
61
+ around_filter :allowblock_#{action}, :only => [:#{action}]
62
+ end_eval
63
+ end
36
64
  end
37
65
  end
@@ -31,46 +31,45 @@ module NeverBlock
31
31
  # end
32
32
  # end
33
33
  #
34
- class FiberPool
34
+ class FiberPool
35
35
 
36
- # gives access to the currently free fibers
37
- attr_reader :fibers
36
+ # gives access to the currently free fibers
37
+ attr_reader :fibers
38
38
 
39
- # Prepare a list of fibers
40
- # that are able to run different
41
- # blocks of code every time
42
- # once a fiber is done with its block
43
- # it attempts to fetch another one
44
- # from the queue.
45
- def initialize(count = 50)
46
- @fibers,@queue = [],[]
47
- count.times do |i|
48
- fiber = Fiber.new do |block|
49
- loop do
50
- block.call
51
- unless @queue.empty?
52
- block = @queue.shift
53
- else
54
- block = Fiber.yield @fibers << Fiber.current
55
- end
56
- end
57
- end
58
- fiber[:neverblock] = true
59
- @fibers << fiber
60
- end
61
- end
39
+ # Prepare a list of fibers that are able to run different blocks of code
40
+ # every time. Once a fiber is done with its block, it attempts to fetch
41
+ # another one from the queue
42
+ def initialize(count = 50)
43
+ @fibers,@queue = [],[]
44
+ count.times do |i|
45
+ fiber = Fiber.new do |block|
46
+ loop do
47
+ block.call
48
+ unless @queue.empty?
49
+ block = @queue.shift
50
+ else
51
+ block = Fiber.yield @fibers << Fiber.current
52
+ end
53
+ end
54
+ end
55
+ fiber[:neverblock] = true
56
+ @fibers << fiber
57
+ end
58
+ end
59
+
60
+ # If there is an available fiber use it, otherwise, leave it to linger
61
+ # in a queue
62
+ def spawn(evented = true, &block)
63
+ if fiber = @fibers.shift
64
+ fiber[:neverblock] = evented
65
+ fiber.resume(block)
66
+ else
67
+ @queue << block
68
+ end
69
+ self # we are keen on hiding our queue
70
+ end
71
+
72
+ end # FiberPool
73
+ end # Pool
74
+ end # NeverBlock
62
75
 
63
- # If there is an available fiber
64
- # use it, otherwise, leave it to linger in a queue
65
- def spawn(evented = true, &block)
66
- if fiber = @fibers.shift
67
- fiber[:neverblock] = evented
68
- fiber.resume(block)
69
- else
70
- @queue << block
71
- end
72
- self # we are keen on hiding our queue
73
- end
74
- end
75
- end
76
- end
@@ -25,19 +25,28 @@ module NeverBlock
25
25
  # end
26
26
  # 32.times do
27
27
  # Fiber.new do
28
- # conn = pool.hold # hold will pause the fiber until a connection is available
29
- # conn.execute('something') # you can use the connection normally now
28
+ # # acquire a connection from the pool
29
+ # pool.hold do |conn|
30
+ # conn.execute('something') # you can use the connection normally now
31
+ # end
30
32
  # end.resume
31
33
  # end
32
34
  #
33
- # The pool has support for transactions, just pass true to the pool#hold method
34
- # and the connection will not be released after the block is finished
35
+ # The pool has support for transactions, just pass true to the
36
+ # pool#hold method and the connection will not be released after the block
37
+ # is finished
35
38
  # It is the responsibility of client code to release the connection
36
39
  class FiberedConnectionPool
37
-
38
- # initialize the connection pool
39
- # using the supplied proc to create the connections
40
- # you can choose to start them eagerly or lazily (lazy by default)
40
+
41
+ attr_reader :size
42
+
43
+ # initialize the connection pool using the supplied proc to create
44
+ # the connections
45
+ # You can choose to start them eagerly or lazily (lazy by default)
46
+ # Available options are
47
+ # :size => the maximum number of connections to be created in the pool
48
+ # :eager => (true|false) indicates whether connections should be
49
+ # created initially or when need
41
50
  def initialize(options = {}, &block)
42
51
  @connections, @busy_connections, @queue = [], {},[]
43
52
  @connection_proc = block
@@ -45,16 +54,13 @@ module NeverBlock
45
54
  if options[:eager]
46
55
  @size.times do
47
56
  @connections << @connection_proc.call
48
- end
57
+ end
49
58
  end
50
59
  end
51
60
 
52
- # If a connection is available,
53
- # pass it to the block, otherwise
54
- # pass the fiber to the queue
55
- # till a connection is available
56
- # when done with a connection
57
- # try to porcess other fibers in the queue
61
+ # If a connection is available, pass it to the block, otherwise pass
62
+ # the fiber to the queue till a connection is available
63
+ # when done with a connection try to porcess other fibers in the queue
58
64
  # before releasing the connection
59
65
  # if inside a transaction, don't release the fiber
60
66
  def hold(transactional = false)
@@ -67,7 +73,7 @@ module NeverBlock
67
73
  yield conn
68
74
  ensure
69
75
  release(fiber, conn) unless transactional
70
- process_queue
76
+ process_queue
71
77
  end
72
78
  end
73
79
 
@@ -106,7 +112,7 @@ module NeverBlock
106
112
  fiber = @queue.shift
107
113
  # What is really happening here?
108
114
  # we are resuming a fiber from within
109
- # another, should we call transfer insted?
115
+ # another, should we call transfer instead?
110
116
  fiber.resume @busy_connections[fiber] = @connections.shift
111
117
  end
112
118
  end
@@ -4,10 +4,8 @@ require 'thin'
4
4
 
5
5
  module Thin
6
6
 
7
- # Patch the thin server to use
8
- # NeverBlock::Pool::FiberPool
9
- # to be able to wrap requests
10
- # in fibers
7
+ # Patch the thin server to use NeverBlock::Pool::FiberPool to be able to
8
+ # wrap requests in fibers
11
9
  class Server
12
10
 
13
11
  DEFAULT_FIBER_POOL_SIZE = 20
@@ -18,17 +16,14 @@ module Thin
18
16
 
19
17
  end # Server
20
18
 
21
- # A request is processed by wrapping it
22
- # in a fiber from the fiber pool. If all
23
- # the fibers are busy the request will
24
- # wait in a queue to be picked up later.
25
- # Meanwhile, the server will still be
26
- # processing requests
19
+ # A request is processed by wrapping it in a fiber from the fiber pool.
20
+ # If all the fibers are busy the request will wait in a queue to be picked up
21
+ # later. Meanwhile, the server will still be processing requests
27
22
  class Connection < EventMachine::Connection
28
23
 
29
24
  def process
30
25
  @request.threaded = false
31
- @backend.server.fiber_pool.spawn{post_process(pre_process)}
26
+ @backend.server.fiber_pool.spawn {post_process(pre_process)}
32
27
  end
33
28
 
34
29
  end # Connection
@@ -1,4 +1,5 @@
1
1
  $:.unshift File.expand_path(File.dirname(__FILE__))
2
2
  require 'neverblock'
3
+ require 'never_block/db/fibered_db_connection'
3
4
  require 'never_block/db/fibered_mysql_connection'
4
- require 'never_block/db/pooled_fibered_mysql_connection'
5
+ require 'never_block/db/pooled_db_connection'
data/neverblock.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "neverblock"
3
- s.version = "0.1.3"
4
- s.date = "2008-09-04"
3
+ s.version = "0.1.4"
4
+ s.date = "2008-09-20"
5
5
  s.summary = "Utilities for non-blocking stack components"
6
6
  s.email = "oldmoe@gmail.com"
7
7
  s.homepage = "http://github.com/oldmoe/neverblock"
@@ -23,14 +23,15 @@ Gem::Specification.new do |s|
23
23
  "lib/never_block/servers/thin.rb",
24
24
  "lib/never_block/servers/mongrel.rb",
25
25
  "lib/never_block/db/fibered_postgres_connection.rb",
26
- "lib/never_block/db/pooled_fibered_postgres_connection.rb",
26
+ "lib/never_block/db/pooled_db_connection.rb",
27
27
  "lib/never_block/db/fibered_mysql_connection.rb",
28
- "lib/never_block/db/pooled_fibered_mysql_connection.rb",
28
+ "lib/never_block/db/fibered_db_connection.rb",
29
29
  "lib/active_record/connection_adapters/neverblock_postgresql_adapter.rb",
30
30
  "lib/active_record/connection_adapters/neverblock_mysql_adapter.rb"
31
31
  ]
32
32
  s.rdoc_options = ["--main", "README"]
33
33
  s.extra_rdoc_files = ["README"]
34
+ s.add_dependency('eventmachine', '>= 0.12.2')
34
35
  end
35
36
 
36
37
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oldmoe-neverblock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muhammad A. Ali
@@ -11,10 +11,18 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2008-09-04 00:00:00 -07:00
14
+ date: 2008-09-20 00:00:00 -07:00
15
15
  default_executable:
16
- dependencies: []
17
-
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: eventmachine
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 0.12.2
25
+ version:
18
26
  description: NeverBlock is a collection of classes and modules that help you write evented non-blocking applications in a seemingly blocking mannner.
19
27
  email: oldmoe@gmail.com
20
28
  executables: []
@@ -38,9 +46,9 @@ files:
38
46
  - lib/never_block/servers/thin.rb
39
47
  - lib/never_block/servers/mongrel.rb
40
48
  - lib/never_block/db/fibered_postgres_connection.rb
41
- - lib/never_block/db/pooled_fibered_postgres_connection.rb
49
+ - lib/never_block/db/pooled_db_connection.rb
42
50
  - lib/never_block/db/fibered_mysql_connection.rb
43
- - lib/never_block/db/pooled_fibered_mysql_connection.rb
51
+ - lib/never_block/db/fibered_db_connection.rb
44
52
  - lib/active_record/connection_adapters/neverblock_postgresql_adapter.rb
45
53
  - lib/active_record/connection_adapters/neverblock_mysql_adapter.rb
46
54
  has_rdoc: true
@@ -1,81 +0,0 @@
1
- module NeverBlock
2
- module DB
3
- # A pooled postgres connection class.
4
- # This class represents a proxy interface
5
- # to a connection pool of fibered postgresql
6
- # connections.
7
- class PooledFiberedPostgresConnection
8
-
9
- # Requires a hash or an array with connection parameters
10
- # and a pool size (defaults to 4)
11
- def initialize(conn_params, size=4)
12
- @pool = NB::Pool::FiberedConnectionPool.new(:size=>size, :eager=>true) do
13
- conn = NB::DB::FPGconn.new(*conn_params) if conn_params.is_a? Array
14
- conn = NB::DB::FPGconn.new(conn_params) if conn_params.is_a? Hash
15
- conn.register_with_event_loop(:em)
16
- conn
17
- end
18
- end
19
-
20
- # A proxy for the connection's exec method
21
- # quries the pool to get a connection first
22
- def exec(query)
23
- @pool.hold do |conn|
24
- conn.exec(query)
25
- end
26
- end
27
-
28
- # This method must be called for transactions to work correctly.
29
- # One cannot just send "begin" as you never know which connection
30
- # will be available next. This method ensures you get the same connection
31
- # while in a transaction.
32
- def begin_db_transaction
33
- @pool.hold(true) do |conn|
34
- conn.exec("begin")
35
- end
36
- end
37
-
38
- # see =begin_db_transaction
39
- def rollback_db_transaction
40
- @pool.hold do |conn|
41
- conn.exec("rollback")
42
- @pool.release(Fiber.current,conn)
43
- end
44
- end
45
-
46
- # see =begin_db_transaction
47
- def commit_db_transaction
48
- @pool.hold do |conn|
49
- conn.exec("commit")
50
- @pool.release(Fiber.current,conn)
51
- end
52
- end
53
-
54
- #close all connections and remove them from the event loop
55
- def close
56
- @pool.all_connections do |conn|
57
- conn.unregister_from_event_loop
58
- conn.close
59
- end
60
- end
61
-
62
- # Pass unknown methods to the connection
63
- def method_missing(method, *args)
64
- @pool.hold do |conn|
65
- conn.send(method, *args)
66
- end
67
- end
68
-
69
- # Pass method queries to the connection
70
- def respond_to?(method)
71
- @pool.hold do |conn|
72
- conn.respond_to?(method)
73
- end
74
- end
75
-
76
- end
77
- end
78
- end
79
-
80
- NB::DB::PFPGconn = NeverBlock::DB::FiberedPostgresConnection
81
-