oldmoe-neverblock 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
-