oldmoe-neverblock 0.1.6 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/lib/never_block.rb +5 -78
  2. data/lib/neverblock.rb +3 -1
  3. data/lib/{never_block/extensions/fiber_extensions.rb → neverblock/core/fiber.rb} +20 -6
  4. data/lib/neverblock/core/pool.rb +72 -0
  5. data/lib/neverblock/core/reactor.rb +50 -0
  6. data/lib/neverblock/core/system/system.rb +38 -0
  7. data/lib/neverblock/core/system/timeout.rb +67 -0
  8. data/lib/{never_block/db/pooled_db_connection.rb → neverblock/io/db/connection.rb} +16 -2
  9. data/lib/neverblock/io/db/drivers/mysql.rb +73 -0
  10. data/lib/neverblock/io/db/drivers/postgres.rb +63 -0
  11. data/lib/neverblock/io/db/fibered_connection_pool.rb +130 -0
  12. data/lib/{never_block → neverblock/io}/db/fibered_mysql_connection.rb +5 -18
  13. data/lib/{never_block/pool/fibered_connection_pool.rb → neverblock/io/db/pool.rb} +25 -40
  14. data/lib/neverblock/io/file.rb +24 -0
  15. data/lib/neverblock/io/io.rb +219 -0
  16. data/lib/neverblock/io/socket.rb +75 -0
  17. data/lib/neverblock_io.rb +6 -0
  18. data/lib/system.rb +4 -0
  19. data/neverblock.gemspec +23 -21
  20. metadata +23 -20
  21. data/lib/active_record/connection_adapters/neverblock_mysql_adapter.rb +0 -68
  22. data/lib/active_record/connection_adapters/neverblock_postgresql_adapter.rb +0 -85
  23. data/lib/never_block/db/fibered_db_connection.rb +0 -72
  24. data/lib/never_block/db/fibered_postgres_connection.rb +0 -64
  25. data/lib/never_block/frameworks/activerecord.rb +0 -37
  26. data/lib/never_block/frameworks/rails.rb +0 -65
  27. data/lib/never_block/pool/fiber_pool.rb +0 -74
  28. data/lib/never_block/servers/mongrel.rb +0 -236
  29. data/lib/never_block/servers/thin.rb +0 -32
  30. data/lib/neverblock-mysql.rb +0 -5
  31. data/lib/neverblock-pg.rb +0 -5
@@ -0,0 +1,75 @@
1
+ # Author:: Mohammad A. Ali (mailto:oldmoe@gmail.com)
2
+ # Copyright:: Copyright (c) 2009 eSpace, Inc.
3
+ # License:: Distributes under the same terms as Ruby
4
+
5
+ require 'socket'
6
+ require 'fcntl'
7
+ require File.expand_path(File.dirname(__FILE__)+'/io')
8
+
9
+ class BasicSocket < IO
10
+
11
+ @@getaddress_method = IPSocket.method(:getaddress)
12
+ def self.getaddress(*args)
13
+ @@getaddress_method.call(*args)
14
+ end
15
+
16
+ alias_method :recv_blocking, :recv
17
+
18
+ def recv_neverblock(*args)
19
+ res = ""
20
+ begin
21
+ old_flags = self.fcntl(Fcntl::F_GETFL, 0)
22
+ res << recv_nonblock(*args)
23
+ self.fcntl(Fcntl::F_SETFL, old_flags)
24
+ rescue Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EINTR
25
+ self.fcntl(Fcntl::F_SETFL, old_flags)
26
+ NB.wait(:read, self)
27
+ retry
28
+ end
29
+ res
30
+ end
31
+
32
+ def recv(*args)
33
+ if NB.neverblocking?
34
+ recv_neverblock(*args)
35
+ else
36
+ recv_blocking(*args)
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ class Socket < BasicSocket
43
+
44
+ alias_method :connect_blocking, :connect
45
+
46
+ def connect_neverblock(server_sockaddr)
47
+ begin
48
+ connect_nonblock(server_sockaddr)
49
+ rescue Errno::EINPROGRESS, Errno::EINTR, Errno::EALREADY, Errno::EWOULDBLOCK
50
+ NB.wait(:write, self)
51
+ retry
52
+ rescue Errno::EISCONN
53
+ # do nothing, we are good
54
+ end
55
+ end
56
+
57
+ def connect(server_sockaddr)
58
+ if NB.neverblocking?
59
+ connect_neverblock(server_sockaddr)
60
+ else
61
+ connect_blocking(server_sockaddr)
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ Object.send(:remove_const, :TCPSocket)
68
+
69
+ class TCPSocket < Socket
70
+ def initialize(*args)
71
+ super(AF_INET, SOCK_STREAM, 0)
72
+ self.connect(Socket.sockaddr_in(*(args.reverse)))
73
+ end
74
+ end
75
+
@@ -0,0 +1,6 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__))
2
+
3
+ require 'neverblock'
4
+ #socket and file will require IO.rb in core
5
+ require 'neverblock/io/socket'
6
+ require 'neverblock/io/file'
@@ -0,0 +1,4 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__))
2
+
3
+ require 'neverblock/core/system/system'
4
+ require 'neverblock/core/system/timeout'
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "neverblock"
3
- s.version = "0.1.6"
4
- s.date = "2008-11-06"
3
+ s.version = "1.0"
4
+ s.date = "2009-07-16"
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"
@@ -10,28 +10,30 @@ Gem::Specification.new do |s|
10
10
  s.authors = ["Muhammad A. Ali", "Ahmed Sobhi", "Osama Brekaa"]
11
11
  s.files = [
12
12
  "neverblock.gemspec",
13
- "README",
14
- "lib/neverblock.rb",
15
- "lib/never_block.rb",
16
- "lib/neverblock-pg.rb",
17
- "lib/neverblock-mysql.rb",
18
- "lib/never_block/extensions/fiber_extensions.rb",
19
- "lib/never_block/pool/fiber_pool.rb",
20
- "lib/never_block/pool/fibered_connection_pool.rb",
21
- "lib/never_block/frameworks/rails.rb",
22
- "lib/never_block/frameworks/activerecord.rb",
23
- "lib/never_block/servers/thin.rb",
24
- "lib/never_block/servers/mongrel.rb",
25
- "lib/never_block/db/fibered_postgres_connection.rb",
26
- "lib/never_block/db/pooled_db_connection.rb",
27
- "lib/never_block/db/fibered_mysql_connection.rb",
28
- "lib/never_block/db/fibered_db_connection.rb",
29
- "lib/active_record/connection_adapters/neverblock_postgresql_adapter.rb",
30
- "lib/active_record/connection_adapters/neverblock_mysql_adapter.rb"
13
+ "README",
14
+ "lib/neverblock/core/reactor.rb",
15
+ "lib/neverblock/core/fiber.rb",
16
+ "lib/neverblock/core/pool.rb",
17
+ "lib/neverblock/core/system/system.rb",
18
+ "lib/neverblock/core/system/timeout.rb",
19
+ "lib/neverblock/io/db/pool.rb",
20
+ "lib/neverblock/io/db/drivers/mysql.rb",
21
+ "lib/neverblock/io/db/drivers/postgres.rb",
22
+ "lib/neverblock/io/db/connection.rb",
23
+ "lib/neverblock/io/db/fibered_connection_pool.rb",
24
+ "lib/neverblock/io/db/fibered_mysql_connection.rb",
25
+ "lib/neverblock/io/file.rb",
26
+ "lib/neverblock/io/socket.rb",
27
+ "lib/neverblock/io/io.rb",
28
+ "lib/system.rb",
29
+ "lib/neverblock.rb",
30
+ "lib/never_block.rb",
31
+ "lib/neverblock_io.rb"
32
+
31
33
  ]
32
34
  s.rdoc_options = ["--main", "README"]
33
35
  s.extra_rdoc_files = ["README"]
34
- s.add_dependency('eventmachine', '>= 0.12.2')
36
+ s.add_dependency('reactor', '>= 0.2.3')
35
37
  end
36
38
 
37
39
 
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.6
4
+ version: "1.0"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muhammad A. Ali
@@ -11,17 +11,18 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2008-11-06 00:00:00 -08:00
14
+ date: 2009-07-16 00:00:00 -07:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
- name: eventmachine
18
+ name: reactor
19
+ type: :runtime
19
20
  version_requirement:
20
21
  version_requirements: !ruby/object:Gem::Requirement
21
22
  requirements:
22
23
  - - ">="
23
24
  - !ruby/object:Gem::Version
24
- version: 0.12.2
25
+ version: 0.2.3
25
26
  version:
26
27
  description: NeverBlock is a collection of classes and modules that help you write evented non-blocking applications in a seemingly blocking mannner.
27
28
  email: oldmoe@gmail.com
@@ -34,25 +35,27 @@ extra_rdoc_files:
34
35
  files:
35
36
  - neverblock.gemspec
36
37
  - README
38
+ - lib/neverblock/core/reactor.rb
39
+ - lib/neverblock/core/fiber.rb
40
+ - lib/neverblock/core/pool.rb
41
+ - lib/neverblock/core/system/system.rb
42
+ - lib/neverblock/core/system/timeout.rb
43
+ - lib/neverblock/io/db/pool.rb
44
+ - lib/neverblock/io/db/drivers/mysql.rb
45
+ - lib/neverblock/io/db/drivers/postgres.rb
46
+ - lib/neverblock/io/db/connection.rb
47
+ - lib/neverblock/io/db/fibered_connection_pool.rb
48
+ - lib/neverblock/io/db/fibered_mysql_connection.rb
49
+ - lib/neverblock/io/file.rb
50
+ - lib/neverblock/io/socket.rb
51
+ - lib/neverblock/io/io.rb
52
+ - lib/system.rb
37
53
  - lib/neverblock.rb
38
54
  - lib/never_block.rb
39
- - lib/neverblock-pg.rb
40
- - lib/neverblock-mysql.rb
41
- - lib/never_block/extensions/fiber_extensions.rb
42
- - lib/never_block/pool/fiber_pool.rb
43
- - lib/never_block/pool/fibered_connection_pool.rb
44
- - lib/never_block/frameworks/rails.rb
45
- - lib/never_block/frameworks/activerecord.rb
46
- - lib/never_block/servers/thin.rb
47
- - lib/never_block/servers/mongrel.rb
48
- - lib/never_block/db/fibered_postgres_connection.rb
49
- - lib/never_block/db/pooled_db_connection.rb
50
- - lib/never_block/db/fibered_mysql_connection.rb
51
- - lib/never_block/db/fibered_db_connection.rb
52
- - lib/active_record/connection_adapters/neverblock_postgresql_adapter.rb
53
- - lib/active_record/connection_adapters/neverblock_mysql_adapter.rb
55
+ - lib/neverblock_io.rb
54
56
  has_rdoc: true
55
57
  homepage: http://github.com/oldmoe/neverblock
58
+ licenses:
56
59
  post_install_message:
57
60
  rdoc_options:
58
61
  - --main
@@ -74,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
77
  requirements: []
75
78
 
76
79
  rubyforge_project:
77
- rubygems_version: 1.2.0
80
+ rubygems_version: 1.3.5
78
81
  signing_key:
79
82
  specification_version: 2
80
83
  summary: Utilities for non-blocking stack components
@@ -1,68 +0,0 @@
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
- super sql, name
15
- id_value || @connection.insert_id
16
- end
17
-
18
- def update_sql(sql, name = nil) #:nodoc:
19
- super
20
- @connection.affected_rows
21
- end
22
-
23
- def connect
24
- #initialize the connection pool
25
- unless @connection
26
- @connection = ::NB::DB::PooledDBConnection.new(@connection_options[0]) do
27
- conn = ::NB::DB::FMysql.init
28
- encoding = @config[:encoding]
29
- if encoding
30
- conn.options(::NB::DB::FMysql::SET_CHARSET_NAME, encoding) rescue nil
31
- end
32
- conn.ssl_set(@config[:sslkey], @config[:sslcert], @config[:sslca], @config[:sslcapath], @config[:sslcipher]) if @config[:sslkey]
33
- conn.real_connect(*@connection_options[1..(@connection_options.length-1)])
34
- NB.neverblock(false) do
35
- conn.query("SET NAMES '#{encoding}'") if encoding
36
- # By default, MySQL 'where id is null' selects the last inserted id.
37
- # Turn this off. http://dev.rubyonrails.org/ticket/6778
38
- conn.query("SET SQL_AUTO_IS_NULL=0")
39
- end
40
- conn
41
- end
42
- else # we have a connection pool, we need to recover a connection
43
- @connection.replace_acquired_connection
44
- end
45
- end
46
-
47
- end
48
-
49
- class ActiveRecord::Base
50
- # Establishes a connection to the database that's used by all Active Record objects
51
- def self.neverblock_mysql_connection(config) # :nodoc:
52
- config = config.symbolize_keys
53
- host = config[:host]
54
- port = config[:port]
55
- socket = config[:socket]
56
- username = config[:username] ? config[:username].to_s : 'root'
57
- password = config[:password].to_s
58
- size = config[:connections] || 4
59
-
60
- if config.has_key?(:database)
61
- database = config[:database]
62
- else
63
- raise ArgumentError, "No database specified. Missing argument: database."
64
- end
65
- MysqlCompat.define_all_hashes_method!
66
- ::ActiveRecord::ConnectionAdapters::NeverBlockMysqlAdapter.new(nil, logger, [size.to_i, host, username, password, database, port, socket, nil], config)
67
- end
68
- end
@@ -1,85 +0,0 @@
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
- # Executes an INSERT query and returns the new record's ID, this wont
13
- # work on earlier versions of PostgreSQL but they don't suppor the async
14
- # interface anyway
15
- # def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
16
- # @connection.exec(sql << " returning id ")
17
- # end
18
-
19
- def connect
20
- @connection = ::NB::DB::PooledDBConnection.new(@connection_parameters[0]) do
21
- conn = ::NB::DB::FiberedPostgresConnection.connect(*@connection_parameters[1..(@connection_parameters.length-1)])
22
- =begin
23
- ::NB::DB::FiberedPostgresConnection.translate_results = false if ::NB::DB::FiberedPostgresConnection.respond_to?(:translate_results=)
24
- # Ignore async_exec and async_query when using postgres-pr.
25
- @async = @config[:allow_concurrency] && @connection.respond_to?(:async_exec)
26
- # Use escape string syntax if available. We cannot do this lazily when encountering
27
- # the first string, because that could then break any transactions in progress.
28
- # See: http://www.postgresql.org/docs/current/static/runtime-config-compatible.html
29
- # If PostgreSQL doesn't know the standard_conforming_strings parameter then it doesn't
30
- # support escape string syntax. Don't override the inherited quoted_string_prefix.
31
- NB.neverblock(false) do
32
- if supports_standard_conforming_strings?
33
- self.class.instance_eval do
34
- define_method(:quoted_string_prefix) { 'E' }
35
- end
36
- end
37
- # Money type has a fixed precision of 10 in PostgreSQL 8.2 and below, and as of
38
- # PostgreSQL 8.3 it has a fixed precision of 19. PostgreSQLColumn.extract_precision
39
- # should know about this but can't detect it there, so deal with it here.
40
- money_precision = (postgresql_version >= 80300) ? 19 : 10
41
- ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn.module_eval(<<-end_eval)
42
- def extract_precision(sql_type)
43
- if sql_type =~ /^money$/
44
- #{money_precision}
45
- else
46
- super
47
- end
48
- end
49
- end_eval
50
- #configure_connection
51
- end
52
- conn
53
- =end
54
- end
55
- end
56
-
57
- # Close then reopen the connection.
58
- def reconnect!
59
- disconnect!
60
- connect
61
- end
62
-
63
- end
64
-
65
- class ActiveRecord::Base
66
- # Establishes a connection to the database that's used by all Active Record objects
67
- def self.neverblock_postgresql_connection(config) # :nodoc:
68
- config = config.symbolize_keys
69
- host = config[:host]
70
- port = config[:port] || 5432
71
- username = config[:username].to_s
72
- password = config[:password].to_s
73
- size = config[:connections] || 4
74
-
75
- if config.has_key?(:database)
76
- database = config[:database]
77
- else
78
- raise ArgumentError, "No database specified. Missing argument: database."
79
- end
80
-
81
- # The postgres drivers don't allow the creation of an unconnected PGconn object,
82
- # so just pass a nil connection object for the time being.
83
- ::ActiveRecord::ConnectionAdapters::NeverBlockPostgreSQLAdapter.new(nil, logger, [size, host, port, nil, nil, database, username, password], config)
84
- end
85
- end
@@ -1,72 +0,0 @@
1
- module NeverBlock
2
- module DB
3
- module FiberedDBConnection
4
-
5
- # Attaches the connection socket to an event loop and adds a callback
6
- # to the fiber's callbacks that unregisters the connection from event loop
7
- # Raises NB::NBError
8
- def register_with_event_loop
9
- #puts ">>>>>register_with_event_loop"
10
- if EM.reactor_running?
11
- @fiber = Fiber.current
12
- #puts ">>>>>register_with_event_loop fiber #{@fiber.inspect}"
13
- # When there's no previous em_connection
14
- key = em_connection_with_pool_key
15
- unless @fiber[key]
16
- @fiber[key] = EM::attach(socket,EMConnectionHandler,self)
17
- @fiber[:callbacks] << self.method(:unregister_from_event_loop)
18
- @fiber[:em_keys] << key
19
- end
20
- else
21
- raise ::NB::NBError.new("FiberedDBConnection: EventMachine reactor not running")
22
- end
23
- end
24
-
25
- # Unattaches the connection socket from the event loop
26
- def unregister_from_event_loop
27
- #puts ">>>>>unregister_from_event_loop #{self.inspect} #{@fiber.inspect}"
28
- key = @fiber[:em_keys].pop
29
- if em_c = @fiber[key]
30
- em_c.detach
31
- @fiber[key] = nil
32
- true
33
- else
34
- false
35
- end
36
- end
37
-
38
- # Removes the unregister_from_event_loop callback from the fiber's
39
- # callbacks. It should be used when errors occur in an already registered
40
- # connection
41
- def remove_unregister_from_event_loop_callbacks
42
- @fiber[:callbacks].delete self.method(:unregister_from_event_loop)
43
- end
44
-
45
- # Closes the connection using event loop
46
- def event_loop_connection_close
47
- key = em_connection_with_pool_key
48
- @fiber[key].close_connection if @fiber[key]
49
- end
50
-
51
- # The callback, this is called whenever
52
- # there is data available at the socket
53
- def resume_command
54
- @fiber.resume if @fiber
55
- end
56
-
57
- private
58
- def em_connection_with_pool_key
59
- "em_#{@fiber[:current_pool_key]}".intern
60
- end
61
- end
62
-
63
- module EMConnectionHandler
64
- def initialize connection
65
- @db_connection = connection
66
- end
67
- def notify_readable
68
- @db_connection.resume_command
69
- end
70
- end
71
- end
72
- end