Permalink
Browse files

fixing mysql and postgres support after reactor

Signed-off-by: Mohammad A. Ali <oldmoe@gmail.com>
  • Loading branch information...
1 parent f49d248 commit 3330b905d7887374b0ace624a42570e2319debef Michael committed with Jul 14, 2009
@@ -1,58 +0,0 @@
-require 'activesupport'
-require 'never_block/frameworks/activerecord'
-require 'active_record/connection_adapters/mysql_adapter'
-require 'neverblock-mysql'
-
-class ActiveRecord::ConnectionAdapters::NeverBlockMysqlAdapter < ActiveRecord::ConnectionAdapters::MysqlAdapter
-
- # Returns 'NeverBlockMySQL' as adapter name for identification purposes
- def adapter_name
- 'NeverBlockMySQL'
- end
-
- def connect
- #initialize the connection pool
- unless @connection
- @connection = ::NB::DB::PooledDBConnection.new(@connection_options[0]) do
- conn = ::NB::DB::FMysql.init
- encoding = @config[:encoding]
- if encoding
- conn.options(::NB::DB::FMysql::SET_CHARSET_NAME, encoding) rescue nil
- end
- conn.ssl_set(@config[:sslkey], @config[:sslcert], @config[:sslca], @config[:sslcapath], @config[:sslcipher]) if @config[:sslkey]
- conn.real_connect(*@connection_options[1..(@connection_options.length-1)])
- NB.neverblock(false) do
- conn.query("SET NAMES '#{encoding}'") if encoding
- # By default, MySQL 'where id is null' selects the last inserted id.
- # Turn this off. http://dev.rubyonrails.org/ticket/6778
- conn.query("SET SQL_AUTO_IS_NULL=0")
- end
- conn
- end
- else # we have a connection pool, we need to recover a connection
- @connection.replace_acquired_connection
- end
- end
-
-end
-
-class ActiveRecord::Base
- # Establishes a connection to the database that's used by all Active Record objects
- def self.neverblock_mysql_connection(config) # :nodoc:
- config = config.symbolize_keys
- host = config[:host]
- port = config[:port]
- socket = config[:socket]
- username = config[:username] ? config[:username].to_s : 'root'
- password = config[:password].to_s
- size = config[:connections] || 4
-
- if config.has_key?(:database)
- database = config[:database]
- else
- raise ArgumentError, "No database specified. Missing argument: database."
- end
- MysqlCompat.define_all_hashes_method!
- ::ActiveRecord::ConnectionAdapters::NeverBlockMysqlAdapter.new(nil, logger, [size.to_i, host, username, password, database, port, socket, nil], config)
- end
-end
@@ -1,85 +0,0 @@
-require 'active_record/connection_adapters/postgresql_adapter'
-require 'neverblock-pg'
-require 'never_block/frameworks/activerecord'
-
-
-class ActiveRecord::ConnectionAdapters::NeverBlockPostgreSQLAdapter < ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
- # Returns 'FiberedPostgreSQL' as adapter name for identification purposes.
- def adapter_name
- 'NeverBlockPostgreSQL'
- end
-
- # Executes an INSERT query and returns the new record's ID, this wont
- # work on earlier versions of PostgreSQL but they don't suppor the async
- # interface anyway
-# def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
-# @connection.exec(sql << " returning id ")
-# end
-
- def connect
- @connection = ::NB::DB::PooledDBConnection.new(@connection_parameters[0]) do
- conn = ::NB::DB::FiberedPostgresConnection.connect(*@connection_parameters[1..(@connection_parameters.length-1)])
-=begin
- ::NB::DB::FiberedPostgresConnection.translate_results = false if ::NB::DB::FiberedPostgresConnection.respond_to?(:translate_results=)
- # Ignore async_exec and async_query when using postgres-pr.
- @async = @config[:allow_concurrency] && @connection.respond_to?(:async_exec)
- # Use escape string syntax if available. We cannot do this lazily when encountering
- # the first string, because that could then break any transactions in progress.
- # See: http://www.postgresql.org/docs/current/static/runtime-config-compatible.html
- # If PostgreSQL doesn't know the standard_conforming_strings parameter then it doesn't
- # support escape string syntax. Don't override the inherited quoted_string_prefix.
- NB.neverblock(false) do
- if supports_standard_conforming_strings?
- self.class.instance_eval do
- define_method(:quoted_string_prefix) { 'E' }
- end
- end
- # Money type has a fixed precision of 10 in PostgreSQL 8.2 and below, and as of
- # PostgreSQL 8.3 it has a fixed precision of 19. PostgreSQLColumn.extract_precision
- # should know about this but can't detect it there, so deal with it here.
- money_precision = (postgresql_version >= 80300) ? 19 : 10
- ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn.module_eval(<<-end_eval)
- def extract_precision(sql_type)
- if sql_type =~ /^money$/
- #{money_precision}
- else
- super
- end
- end
- end_eval
- #configure_connection
- end
- conn
-=end
- end
- end
-
- # Close then reopen the connection.
- def reconnect!
- disconnect!
- connect
- end
-
-end
-
-class ActiveRecord::Base
- # Establishes a connection to the database that's used by all Active Record objects
- def self.neverblock_postgresql_connection(config) # :nodoc:
- config = config.symbolize_keys
- host = config[:host]
- port = config[:port] || 5432
- username = config[:username].to_s
- password = config[:password].to_s
- size = config[:connections] || 4
-
- if config.has_key?(:database)
- database = config[:database]
- else
- raise ArgumentError, "No database specified. Missing argument: database."
- end
-
- # The postgres drivers don't allow the creation of an unconnected PGconn object,
- # so just pass a nil connection object for the time being.
- ::ActiveRecord::ConnectionAdapters::NeverBlockPostgreSQLAdapter.new(nil, logger, [size, host, port, nil, nil, database, username, password], config)
- end
-end
View
@@ -21,7 +21,7 @@ class File < IO
def self.neverblock(*methods)
methods.each do |method|
class_eval %{
- def #{method}(args)
+ def #{method}(*args)
return rb_#{method}(*args) unless NB.neverblocking?
@@queue << [self, :#{method}, args, NB::Fiber.current, NB.reactor]
NB::Fiber.yield
View
@@ -121,7 +121,7 @@ def gets(sep=$/)
sep = "\n\n" if sep == ""
sep = $/ if sep.nil?
while res.index(sep).nil?
- break if (c = read(1)).nil
+ break if (c = read(1)).nil?
res << c
end
$_ = res
@@ -1,37 +0,0 @@
-require 'activerecord'
-
-# Patch ActiveRecord to store transaction depth information
-# in fibers instead of threads. AR does not support nested
-# transactions which makes the job easy.
-# We also need to override the scoped methods to store
-# the scope in the fiber context
-class ActiveRecord::Base
-
- def single_threaded_scoped_methods #:nodoc:
- scoped_methods = (Fiber.current[:scoped_methods] ||= {})
- scoped_methods[self] ||= []
- end
-
- def self.transaction(&block)
- increment_open_transactions
- begin
- connection.transaction(Fiber.current['start_db_transaction'], &block)
- ensure
- decrement_open_transactions
- end
- end
-
- private
-
- def self.increment_open_transactions #:nodoc:
- open = Fiber.current['open_transactions'] ||= 0
- Fiber.current['start_db_transaction'] = open.zero?
- Fiber.current['open_transactions'] = open + 1
- end
-
- def self.decrement_open_transactions #:nodoc:
- Fiber.current['open_transactions'] -= 1
- end
-
-end
-
@@ -0,0 +1,88 @@
+# Require original mysql adapter as we'll just extend it
+require 'active_record/connection_adapters/mysql_adapter'
+
+class ActiveRecord::ConnectionAdapters::ConnectionPool
+
+ def current_connection_id #:nodoc:
+ NB::Fiber.current.object_id
+ end
+
+ def checkout
+ # Checkout an available connection
+ loop do
+ conn = if @checked_out.size < @connections.size
+ checkout_existing_connection
+ elsif @connections.size < @size
+ checkout_new_connection
+ end
+ return conn if conn
+ # No connections available; wait for one
+ @waiting ||= []
+ NB::Fiber.yield @waiting << NB::Fiber.current
+ end
+ end
+
+ def checkin(conn)
+ conn.run_callbacks :checkin
+ @checked_out.delete conn
+ if @waiting && @waiting.size > 0
+ @waiting.shift.resume
+ end
+ end
+
+end
+
+class ActiveRecord::ConnectionAdapters::NeverBlockMysqlAdapter < ActiveRecord::ConnectionAdapters::MysqlAdapter
+
+ # Returns 'NeverBlockMySQL' as adapter name for identification purposes
+ def adapter_name
+ 'NeverBlockMySQL'
+ end
+
+ def configure_connection
+ NB.neverblock(false) do
+ encoding = @config[:encoding]
+ execute("SET NAMES '#{encoding}'") if encoding
+
+ # By default, MySQL 'where id is null' selects the last inserted id.
+ # Turn this off. http://dev.rubyonrails.org/ticket/6778
+ execute("SET SQL_AUTO_IS_NULL=0")
+ end
+ end
+
+end
+
+
+class ActiveRecord::Base
+ # Establishes a connection to the database that's used by all Active Record objects.
+ def self.neverblock_mysql_connection(config) # :nodoc:
+ config = config.symbolize_keys
+ host = config[:host]
+ port = config[:port]
+ socket = config[:socket]
+ username = config[:username] ? config[:username].to_s : 'root'
+ password = config[:password].to_s
+
+ if config.has_key?(:database)
+ database = config[:database]
+ else
+ raise ArgumentError, "No database specified. Missing argument: database."
+ end
+
+ # Require the MySQL driver and define Mysql::Result.all_hashes
+ unless defined? Mysql
+ begin
+ require_library_or_gem('mysqlplus')
+ rescue LoadError
+ $stderr.puts 'mysqlplus is required'
+ raise
+ end
+ end
+ MysqlCompat.define_all_hashes_method!
+
+ mysql = NB::DB::FiberedMysqlConnection.init
+ mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslca] || config[:sslkey]
+
+ ::ActiveRecord::ConnectionAdapters::NeverBlockMysqlAdapter.new(mysql, logger, [host, username, password, database, port, socket], config)
+ end
+end
@@ -0,0 +1,71 @@
+# Require original mysql adapter as we'll just extend it
+require 'active_record/connection_adapters/postgresql_adapter'
+
+class ActiveRecord::ConnectionAdapters::NeverBlockPostgreSQLAdapter < ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
+ # Returns 'FiberedPostgreSQL' as adapter name for identification purposes.
+ def adapter_name
+ 'NeverBlockPostgreSQL'
+ end
+
+ def connect
+ @connection = ::NB::DB::FiberedPostgresConnection.connect(*@connection_parameters[1..(@connection_parameters.length-1)])
+ end
+
+ # Close then reopen the connection.
+ def reconnect!
+ disconnect!
+ connect
+ end
+
+end
+
+class ActiveRecord::ConnectionAdapters::ConnectionPool
+ def current_connection_id #:nodoc:
+ NB::Fiber.current.object_id
+ end
+
+ def checkout
+ # Checkout an available connection
+ loop do
+ conn = if @checked_out.size < @connections.size
+ checkout_existing_connection
+ elsif @connections.size < @size
+ checkout_new_connection
+ end
+ return conn if conn
+ # No connections available; wait for one
+ @waiting ||= []
+ NB::Fiber.yield @waiting << NB::Fiber.current
+ end
+ end
+
+ def checkin(conn)
+ conn.run_callbacks :checkin
+ @checked_out.delete conn
+ if @waiting && @waiting.size > 0
+ @waiting.shift.resume
+ end
+ end
+end
+
+class ActiveRecord::Base
+ # Establishes a connection to the database that's used by all Active Record objects
+ def self.neverblock_postgresql_connection(config) # :nodoc:
+ config = config.symbolize_keys
+ host = config[:host]
+ port = config[:port] || 5432
+ username = config[:username].to_s
+ password = config[:password].to_s
+ size = config[:connections] || 4
+
+ if config.has_key?(:database)
+ database = config[:database]
+ else
+ raise ArgumentError, "No database specified. Missing argument: database."
+ end
+
+ # The postgres drivers don't allow the creation of an unconnected PGconn object,
+ # so just pass a nil connection object for the time being.
+ ::ActiveRecord::ConnectionAdapters::NeverBlockPostgreSQLAdapter.new(nil, logger, [size, host, port, nil, nil, database, username, password], config)
+ end
+end
Oops, something went wrong.

0 comments on commit 3330b90

Please sign in to comment.