oldmoe-neverblock 0.1.0 → 0.1.1

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