oldmoe-neverblock 0.1.0 → 0.1.1

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.
@@ -0,0 +1,78 @@
1
+ require 'activesupport'
2
+ require 'never_block/frameworks/activerecord'
3
+ require 'active_record/connection_adapters/mysql_adapter'
4
+ require 'neverblock-mysql'
5
+
6
+ class ActiveRecord::ConnectionAdapters::NeverBlockMysqlAdapter < ActiveRecord::ConnectionAdapters::MysqlAdapter
7
+
8
+ # Returns 'NeverBlockMySQL' as adapter name for identification purposes
9
+ def adapter_name
10
+ 'NeverBlockMySQL'
11
+ end
12
+
13
+ def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
14
+ begin_db_transaction
15
+ super sql, name
16
+ id_value || @connection.insert_id
17
+ commit_db_transaction
18
+ end
19
+
20
+ def update_sql(sql, name = nil) #:nodoc:
21
+ begin_db_transaction
22
+ super
23
+ @connection.affected_rows
24
+ commit_db_transaction
25
+ end
26
+
27
+ def begin_db_transaction
28
+ @connection.begin_db_transaction
29
+ end
30
+
31
+ def commit_db_transaction
32
+ @connection.commit_db_transaction
33
+ end
34
+
35
+ def rollback_db_transaction
36
+ @connection.rollback_db_transaction
37
+ end
38
+
39
+ def connect
40
+ @connection = ::NB::DB::PooledFiberedMysqlConnection.new(@connection_options.shift) do
41
+ conn = ::NB::DB::FMysql.init
42
+ encoding = @config[:encoding]
43
+ if encoding
44
+ conn.options(::NB::DB::FMysql::SET_CHARSET_NAME, encoding) rescue nil
45
+ end
46
+ conn.ssl_set(@config[:sslkey], @config[:sslcert], @config[:sslca], @config[:sslcapath], @config[:sslcipher]) if @config[:sslkey]
47
+ conn.real_connect(*@connection_options)
48
+ conn.query("SET NAMES '#{encoding}'") if encoding
49
+ # By default, MySQL 'where id is null' selects the last inserted id.
50
+ # Turn this off. http://dev.rubyonrails.org/ticket/6778
51
+ # conn.query("SET SQL_AUTO_IS_NULL=0")
52
+ conn.register_with_event_loop(:em)
53
+ conn
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ class ActiveRecord::Base
60
+ # Establishes a connection to the database that's used by all Active Record objects
61
+ def self.neverblock_mysql_connection(config) # :nodoc:
62
+ config = config.symbolize_keys
63
+ host = config[:host]
64
+ port = config[:port]
65
+ socket = config[:socket]
66
+ username = config[:username] ? config[:username].to_s : 'root'
67
+ password = config[:password].to_s
68
+ size = config[:connections] || 4
69
+
70
+ if config.has_key?(:database)
71
+ database = config[:database]
72
+ else
73
+ raise ArgumentError, "No database specified. Missing argument: database."
74
+ end
75
+ MysqlCompat.define_all_hashes_method!
76
+ ::ActiveRecord::ConnectionAdapters::NeverBlockMysqlAdapter.new(nil, logger, [size.to_i, host, username, password, database, port, socket, nil], config)
77
+ end
78
+ end
@@ -0,0 +1,97 @@
1
+ require 'active_record/connection_adapters/postgresql_adapter'
2
+ require 'neverblock-pg'
3
+ require 'never_block/frameworks/activerecord'
4
+
5
+
6
+ class ActiveRecord::ConnectionAdapters::NeverBlockPostgreSQLAdapter < ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
7
+ # Returns 'FiberedPostgreSQL' as adapter name for identification purposes.
8
+ def adapter_name
9
+ 'NeverBlockPostgreSQL'
10
+ end
11
+
12
+ def begin_db_transaction
13
+ @connection.begin_db_transaction
14
+ end
15
+
16
+ def commit_db_transaction
17
+ @connection.commit_db_transaction
18
+ end
19
+
20
+ def rollback_db_transaction
21
+ @connection.rollback_db_transaction
22
+ end
23
+ # Executes an INSERT query and returns the new record's ID, this wont
24
+ # work on earlier versions of PostgreSQL but they don't suppor the async
25
+ # interface anyway
26
+ def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
27
+ @connection.exec(sql << " returning id ")
28
+ end
29
+
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
+ @connection.begin_db_transaction
45
+ if supports_standard_conforming_strings?
46
+ self.class.instance_eval do
47
+ define_method(:quoted_string_prefix) { 'E' }
48
+ end
49
+ end
50
+
51
+ # Money type has a fixed precision of 10 in PostgreSQL 8.2 and below, and as of
52
+ # PostgreSQL 8.3 it has a fixed precision of 19. PostgreSQLColumn.extract_precision
53
+ # should know about this but can't detect it there, so deal with it here.
54
+ money_precision = (postgresql_version >= 80300) ? 19 : 10
55
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn.module_eval(<<-end_eval)
56
+ def extract_precision(sql_type)
57
+ if sql_type =~ /^money$/
58
+ #{money_precision}
59
+ else
60
+ super
61
+ end
62
+ end
63
+ end_eval
64
+
65
+ configure_connection
66
+ @connection.commit_db_transaction
67
+ end
68
+
69
+ # Close then reopen the connection.
70
+ def reconnect!
71
+ disconnect!
72
+ connect
73
+ end
74
+
75
+ end
76
+
77
+ class ActiveRecord::Base
78
+ # Establishes a connection to the database that's used by all Active Record objects
79
+ def self.neverblock_postgresql_connection(config) # :nodoc:
80
+ config = config.symbolize_keys
81
+ host = config[:host]
82
+ port = config[:port] || 5432
83
+ username = config[:username].to_s
84
+ password = config[:password].to_s
85
+ size = config[:connections] || 4
86
+
87
+ if config.has_key?(:database)
88
+ database = config[:database]
89
+ else
90
+ raise ArgumentError, "No database specified. Missing argument: database."
91
+ end
92
+
93
+ # The postgres drivers don't allow the creation of an unconnected PGconn object,
94
+ # so just pass a nil connection object for the time being.
95
+ ::ActiveRecord::ConnectionAdapters::NeverBlockPostgreSQLAdapter.new(nil, logger, [size, host, port, nil, nil, database, username, password], config)
96
+ end
97
+ end
@@ -0,0 +1,97 @@
1
+ require 'mysql'
2
+
3
+ module NeverBlock
4
+
5
+ module DB
6
+ # A modified postgres connection driver
7
+ # builds on the original pg driver.
8
+ # This driver is able to register the socket
9
+ # at a certain backend (EM or Rev)
10
+ # and then whenever the query is executed
11
+ # within the scope of a friendly fiber
12
+ # it will be done in async mode and the fiber
13
+ # will yield
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
28
+
29
+ # Assuming the use of NeverBlock fiber extensions and that the exec is run in
30
+ # the context of a fiber. One that have the value :neverblock set to true.
31
+ # All neverblock IO classes check this value, setting it to false will force
32
+ # the execution in a blocking way.
33
+ 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
51
+ 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
72
+ end
73
+
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
79
+
80
+ end #FiberedPostgresConnection
81
+
82
+ # A connection handler for EM
83
+ # More to follow.
84
+ module EMConnectionHandler
85
+ def initialize connection
86
+ @connection = connection
87
+ end
88
+ def notify_readable
89
+ @connection.process_command
90
+ end
91
+ end
92
+
93
+ end #DB
94
+
95
+ end #NeverBlock
96
+
97
+ NeverBlock::DB::FMysql = NeverBlock::DB::FiberedMysqlConnection
@@ -0,0 +1,109 @@
1
+ require 'pg'
2
+
3
+ module NeverBlock
4
+
5
+ module DB
6
+ # A modified postgres connection driver
7
+ # builds on the original pg driver.
8
+ # This driver is able to register the socket
9
+ # at a certain backend (EM or Rev)
10
+ # and then whenever the query is executed
11
+ # within the scope of a friendly fiber
12
+ # it will be done in async mode and the fiber
13
+ # will yield
14
+ 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
+
28
+ # Assuming the use of NeverBlock fiber extensions and that the exec is run in
29
+ # the context of a fiber. One that have the value :neverblock set to true.
30
+ # All neverblock IO classes check this value, setting it to false will force
31
+ # the execution in a blocking way.
32
+ 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
50
+ 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
62
+ end
63
+
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
73
+
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
90
+ end
91
+
92
+ 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
+
105
+ end #DB
106
+
107
+ end #NeverBlock
108
+
109
+ NeverBlock::DB::FPGconn = NeverBlock::DB::FiberedPostgresConnection
@@ -0,0 +1,78 @@
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 PooledFiberedMysqlConnection
8
+
9
+ # Requires a hash or an array with connection parameters
10
+ # and a pool size (defaults to 4)
11
+ def initialize(size=4, &block)
12
+ @pool = NB::Pool::FiberedConnectionPool.new(:size=>size, :eager=>true) do
13
+ yield
14
+ end
15
+ end
16
+
17
+ # A proxy for the connection's exec method
18
+ # quries the pool to get a connection first
19
+ def exec(query)
20
+ @pool.hold do |conn|
21
+ conn.query(query)
22
+ end
23
+ end
24
+
25
+ alias :query :exec
26
+ # This method must be called for transactions to work correctly.
27
+ # One cannot just send "begin" as you never know which connection
28
+ # will be available next. This method ensures you get the same connection
29
+ # while in a transaction.
30
+ def begin_db_transaction
31
+ @pool.hold(true) do |conn|
32
+ conn.exec("begin")
33
+ end
34
+ end
35
+
36
+ # see =begin_db_transaction
37
+ def rollback_db_transaction
38
+ @pool.hold do |conn|
39
+ conn.exec("rollback")
40
+ @pool.release(Fiber.current,conn)
41
+ end
42
+ end
43
+
44
+ # see =begin_db_transaction
45
+ def commit_db_transaction
46
+ @pool.hold do |conn|
47
+ conn.exec("commit")
48
+ @pool.release(Fiber.current,conn)
49
+ end
50
+ end
51
+
52
+ #close all connections and remove them from the event loop
53
+ def close
54
+ @pool.all_connections do |conn|
55
+ conn.unregister_from_event_loop
56
+ conn.close
57
+ end
58
+ end
59
+
60
+ # Pass unknown methods to the connection
61
+ def method_missing(method, *args)
62
+ @pool.hold do |conn|
63
+ conn.send(method, *args)
64
+ end
65
+ end
66
+
67
+ # Pass method queries to the connection
68
+ def respond_to?(method)
69
+ @pool.hold do |conn|
70
+ conn.respond_to?(method)
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+ end
77
+
78
+ NeverBlock::DB::PFMysql = NeverBlock::DB::PooledFiberedMysqlConnection
@@ -0,0 +1,81 @@
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
+
@@ -2,16 +2,21 @@
2
2
  # Copyright:: Copyright (c) 2008 eSpace, Inc.
3
3
  # License:: Distributes under the same terms as Ruby
4
4
 
5
- require 'fiber'
5
+ # If this file is meant to be used out of neverblock, then uncomment
6
+ # the following line
7
+ #require 'fiber'
6
8
 
7
9
  class Fiber
8
10
 
9
- #Attribute Reference--Returns the value of a fiber-local variable, using either a symbol or a string name. If the specified variable does not exist, returns nil.
11
+ #Attribute Reference--Returns the value of a fiber-local variable, using
12
+ #either a symbol or a string name. If the specified variable does not exist,
13
+ #returns nil.
10
14
  def [](key)
11
15
  local_fiber_variables[key]
12
16
  end
13
17
 
14
- #Attribute Assignment--Sets or creates the value of a fiber-local variable, using either a symbol or a string. See also Fiber#[].
18
+ #Attribute Assignment--Sets or creates the value of a fiber-local variable,
19
+ #using either a symbol or a string. See also Fiber#[].
15
20
  def []=(key,value)
16
21
  local_fiber_variables[key] = value
17
22
  end
@@ -1,11 +1,17 @@
1
- require 'never_block/frameworks/rails'
2
1
  require 'activerecord'
3
2
 
4
3
  # Patch ActiveRecord to store transaction depth information
5
4
  # in fibers instead of threads. AR does not support nested
6
5
  # transactions which makes the job easy.
6
+ # We also need to override the scoped methods to store
7
+ # the scope in the fiber context
7
8
  class ActiveRecord::Base
8
9
 
10
+ def single_threaded_scoped_methods #:nodoc:
11
+ scoped_methods = (Fiber.current[:scoped_methods] ||= {})
12
+ scoped_methods[self] ||= []
13
+ end
14
+
9
15
  def self.transaction(&block)
10
16
  increment_open_transactions
11
17
  begin
@@ -1,4 +1,5 @@
1
- require 'actionpack'
1
+ #require 'actionpack'
2
+ require 'action_controller'
2
3
 
3
4
  # Rails tries to protect dispatched actions
4
5
  # by wrapping them in a synchronized code
@@ -5,7 +5,7 @@
5
5
  # Copyright:: Copyright (c) 2008 eSpace, Inc.
6
6
  # License:: Distributes under the same terms as Ruby
7
7
 
8
- require 'fiber'
8
+ #require 'fiber'
9
9
 
10
10
  module NeverBlock
11
11
  module Pool
@@ -64,7 +64,7 @@ module NeverBlock
64
64
  # use it, otherwise, leave it to linger in a queue
65
65
  def spawn(evented = true, &block)
66
66
  if fiber = @fibers.shift
67
- fiber[:evented] = evented
67
+ fiber[:neverblock] = evented
68
68
  fiber.resume(block)
69
69
  else
70
70
  @queue << block
@@ -78,7 +78,11 @@ module NeverBlock
78
78
  @busy_connections.delete(fiber)
79
79
  @connections << conn
80
80
  end
81
-
81
+
82
+ def all_connections
83
+ (@connections + @busy_connections.values).each {|conn| yield(conn)}
84
+ end
85
+
82
86
  private
83
87
 
84
88
  # Can we find a connection?
@@ -31,4 +31,16 @@ module Thin
31
31
 
32
32
  end # Connection
33
33
 
34
+ module Backends
35
+ class Base
36
+ def config
37
+ # EM.epoll
38
+ # Set the maximum number of socket descriptors that the server may open.
39
+ # The process needs to have required privilege to set it higher the 1024 on
40
+ # some systems.
41
+ @maximum_connections = EventMachine.set_descriptor_table_size(@maximum_connections) unless Thin.win?
42
+ end
43
+ end
44
+ end # Backends
45
+
34
46
  end # Thin
data/lib/never_block.rb CHANGED
@@ -4,7 +4,70 @@
4
4
 
5
5
  $:.unshift File.expand_path(File.dirname(__FILE__))
6
6
 
7
- require 'fiber'
7
+ unless defined? Fiber
8
+ require 'thread'
9
+ require 'singleton'
10
+ class FiberError < StandardError; end
11
+ class Fiber
12
+ def initialize
13
+ raise ArgumentError, 'new Fiber requires a block' unless block_given?
14
+
15
+ @yield = Queue.new
16
+ @resume = Queue.new
17
+
18
+ @thread = Thread.new{ @yield.push [ *yield(*@resume.pop) ] }
19
+ @thread.abort_on_exception = true
20
+ @thread[:fiber] = self
21
+ end
22
+ attr_reader :thread
23
+
24
+ def resume *args
25
+ raise FiberError, 'dead fiber called' unless @thread.alive?
26
+ @resume.push(args)
27
+ result = @yield.pop
28
+ result.size > 1 ? result : result.first
29
+ end
30
+
31
+ def yield *args
32
+ @yield.push(args)
33
+ result = @resume.pop
34
+ result.size > 1 ? result : result.first
35
+ end
36
+
37
+ def self.yield *args
38
+ raise FiberError, "can't yield from root fiber" unless fiber = Thread.current[:fiber]
39
+ fiber.yield(*args)
40
+ end
41
+
42
+ def self.current
43
+ Thread.current[:fiber] or raise FiberError, 'not inside a fiber'
44
+ end
45
+
46
+ def inspect
47
+ "#<#{self.class}:0x#{self.object_id.to_s(16)}>"
48
+ end
49
+ end
50
+
51
+ class RootFiber < Fiber
52
+ include Singleton
53
+ def initialize
54
+ end
55
+
56
+ def resume *args
57
+ raise FiberError, "can't resume root fiber"
58
+ end
59
+
60
+ def yield *args
61
+ raise FiberError, "can't yield from root fiber"
62
+ end
63
+ end
64
+
65
+ #attach the root fiber to the main thread
66
+ Thread.main[:fiber] = RootFiber.instance
67
+ else
68
+ require 'fiber'
69
+ end
70
+
8
71
  require 'never_block/extensions/fiber_extensions'
9
72
  require 'never_block/pool/fiber_pool'
10
73
  require 'never_block/pool/fibered_connection_pool'
@@ -12,4 +75,4 @@ require 'never_block/pool/fibered_connection_pool'
12
75
  module NeverBlock
13
76
  end
14
77
 
15
- NB = NeverBlock
78
+ NB = NeverBlock
@@ -0,0 +1,4 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__))
2
+ require 'neverblock'
3
+ require 'never_block/db/fibered_mysql_connection'
4
+ require 'never_block/db/pooled_fibered_mysql_connection'
@@ -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'
data/neverblock.gemspec CHANGED
@@ -1,25 +1,35 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "neverblock"
3
- s.version = "0.1.0"
3
+ s.version = "0.1.1"
4
4
  s.date = "2008-08-13"
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"
8
8
  s.description = "NeverBlock is a collection of classes and modules that help you write evented non-blocking applications in a seemingly blocking mannner."
9
9
  s.has_rdoc = true
10
- s.authors = ["Muhammad A. Ali", "Ahmed Sobhi"]
10
+ s.authors = ["Muhammad A. Ali", "Ahmed Sobhi", "Osama Brekaa"]
11
11
  s.files = [
12
12
  "neverblock.gemspec",
13
13
  "README",
14
14
  "lib/neverblock.rb",
15
15
  "lib/never_block.rb",
16
+ "lib/neverblock-pg.rb",
17
+ "lib/neverblock-mysql.rb",
16
18
  "lib/never_block/extensions/fiber_extensions.rb",
17
19
  "lib/never_block/pool/fiber_pool.rb",
18
20
  "lib/never_block/pool/fibered_connection_pool.rb",
19
21
  "lib/never_block/frameworks/rails.rb",
20
22
  "lib/never_block/frameworks/activerecord.rb",
21
- "lib/never_block/servers/thin.rb"]
23
+ "lib/never_block/servers/thin.rb",
24
+ "lib/never_block/db/fibered_postgres_connection.rb",
25
+ "lib/never_block/db/pooled_fibered_postgres_connection.rb",
26
+ "lib/never_block/db/fibered_mysql_connection.rb",
27
+ "lib/never_block/db/pooled_fibered_mysql_connection.rb",
28
+ "lib/active_record/connection_adapters/neverblock_postgresql_adapter.rb",
29
+ "lib/active_record/connection_adapters/neverblock_mysql_adapter.rb"
30
+ ]
22
31
  s.rdoc_options = ["--main", "README"]
23
32
  s.extra_rdoc_files = ["README"]
24
33
  end
25
34
 
35
+
metadata CHANGED
@@ -1,11 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oldmoe-neverblock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muhammad A. Ali
8
8
  - Ahmed Sobhi
9
+ - Osama Brekaa
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
@@ -27,12 +28,20 @@ files:
27
28
  - README
28
29
  - lib/neverblock.rb
29
30
  - lib/never_block.rb
31
+ - lib/neverblock-pg.rb
32
+ - lib/neverblock-mysql.rb
30
33
  - lib/never_block/extensions/fiber_extensions.rb
31
34
  - lib/never_block/pool/fiber_pool.rb
32
35
  - lib/never_block/pool/fibered_connection_pool.rb
33
36
  - lib/never_block/frameworks/rails.rb
34
37
  - lib/never_block/frameworks/activerecord.rb
35
38
  - lib/never_block/servers/thin.rb
39
+ - lib/never_block/db/fibered_postgres_connection.rb
40
+ - lib/never_block/db/pooled_fibered_postgres_connection.rb
41
+ - lib/never_block/db/fibered_mysql_connection.rb
42
+ - lib/never_block/db/pooled_fibered_mysql_connection.rb
43
+ - lib/active_record/connection_adapters/neverblock_postgresql_adapter.rb
44
+ - lib/active_record/connection_adapters/neverblock_mysql_adapter.rb
36
45
  has_rdoc: true
37
46
  homepage: http://github.com/oldmoe/neverblock
38
47
  post_install_message: