oldmoe-neverblock 0.1.6 → 1.0

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.
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