em-synchrony 1.0.0 → 1.0.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.
- data/Gemfile +3 -1
- data/README.md +173 -170
- data/Rakefile +3 -5
- data/em-synchrony.gemspec +1 -1
- data/lib/active_record/connection_adapters/em_mysql2_adapter.rb +47 -0
- data/lib/em-synchrony.rb +33 -10
- data/lib/em-synchrony/activerecord.rb +103 -5
- data/lib/em-synchrony/amqp.rb +180 -0
- data/lib/em-synchrony/connection_pool.rb +3 -2
- data/lib/em-synchrony/core_ext.rb +10 -0
- data/lib/em-synchrony/em-hiredis.rb +103 -24
- data/lib/em-synchrony/em-mongo.rb +19 -0
- data/lib/em-synchrony/em-multi.rb +4 -2
- data/lib/em-synchrony/mongo.rb +6 -2
- data/lib/em-synchrony/mysql2.rb +16 -0
- data/lib/em-synchrony/tcpsocket.rb +5 -4
- data/lib/em-synchrony/thread.rb +108 -7
- data/spec/activerecord_spec.rb +108 -49
- data/spec/amqp_spec.rb +146 -0
- data/spec/connection_pool_spec.rb +4 -4
- data/spec/em-mongo_spec.rb +26 -0
- data/spec/helper/all.rb +1 -7
- data/spec/hiredis_spec.rb +24 -1
- data/spec/http_spec.rb +8 -8
- data/spec/multi_spec.rb +13 -0
- data/spec/mysql2_spec.rb +13 -0
- data/spec/synchrony_spec.rb +29 -10
- data/spec/tcpsocket_spec.rb +10 -0
- data/spec/thread_spec.rb +191 -0
- metadata +15 -10
- data/lib/em-synchrony/active_record/connection_adapters/em_mysql2_adapter.rb +0 -18
- data/lib/em-synchrony/active_record/patches.rb +0 -132
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-synchrony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-04-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
16
|
-
requirement: &
|
16
|
+
requirement: &2152409200 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 1.0.0.beta.1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2152409200
|
25
25
|
description: Fiber aware EventMachine libraries
|
26
26
|
email:
|
27
27
|
- ilya@igvita.com
|
@@ -43,11 +43,12 @@ files:
|
|
43
43
|
- examples/go/consumer-publisher.rb
|
44
44
|
- examples/go/go.rb
|
45
45
|
- examples/nethttp.rb
|
46
|
+
- lib/active_record/connection_adapters/em_mysql2_adapter.rb
|
46
47
|
- lib/em-synchrony.rb
|
47
|
-
- lib/em-synchrony/active_record/connection_adapters/em_mysql2_adapter.rb
|
48
|
-
- lib/em-synchrony/active_record/patches.rb
|
49
48
|
- lib/em-synchrony/activerecord.rb
|
49
|
+
- lib/em-synchrony/amqp.rb
|
50
50
|
- lib/em-synchrony/connection_pool.rb
|
51
|
+
- lib/em-synchrony/core_ext.rb
|
51
52
|
- lib/em-synchrony/em-hiredis.rb
|
52
53
|
- lib/em-synchrony/em-http.rb
|
53
54
|
- lib/em-synchrony/em-jack.rb
|
@@ -65,6 +66,7 @@ files:
|
|
65
66
|
- lib/em-synchrony/tcpsocket.rb
|
66
67
|
- lib/em-synchrony/thread.rb
|
67
68
|
- spec/activerecord_spec.rb
|
69
|
+
- spec/amqp_spec.rb
|
68
70
|
- spec/beanstalk_spec.rb
|
69
71
|
- spec/connection_pool_spec.rb
|
70
72
|
- spec/em-mongo_spec.rb
|
@@ -79,11 +81,13 @@ files:
|
|
79
81
|
- spec/keyboard_spec.rb
|
80
82
|
- spec/memcache_spec.rb
|
81
83
|
- spec/mongo_spec.rb
|
84
|
+
- spec/multi_spec.rb
|
82
85
|
- spec/mysql2_spec.rb
|
83
86
|
- spec/redis_spec.rb
|
84
87
|
- spec/remcached_spec.rb
|
85
88
|
- spec/synchrony_spec.rb
|
86
89
|
- spec/tcpsocket_spec.rb
|
90
|
+
- spec/thread_spec.rb
|
87
91
|
- spec/timer_spec.rb
|
88
92
|
homepage: http://github.com/igrigorik/em-synchrony
|
89
93
|
licenses: []
|
@@ -97,9 +101,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
97
101
|
- - ! '>='
|
98
102
|
- !ruby/object:Gem::Version
|
99
103
|
version: '0'
|
100
|
-
segments:
|
101
|
-
- 0
|
102
|
-
hash: 1015811308506799380
|
103
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
105
|
none: false
|
105
106
|
requirements:
|
@@ -108,12 +109,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
109
|
version: '0'
|
109
110
|
requirements: []
|
110
111
|
rubyforge_project: em-synchrony
|
111
|
-
rubygems_version: 1.8.
|
112
|
+
rubygems_version: 1.8.10
|
112
113
|
signing_key:
|
113
114
|
specification_version: 3
|
114
115
|
summary: Fiber aware EventMachine libraries
|
115
116
|
test_files:
|
116
117
|
- spec/activerecord_spec.rb
|
118
|
+
- spec/amqp_spec.rb
|
117
119
|
- spec/beanstalk_spec.rb
|
118
120
|
- spec/connection_pool_spec.rb
|
119
121
|
- spec/em-mongo_spec.rb
|
@@ -128,9 +130,12 @@ test_files:
|
|
128
130
|
- spec/keyboard_spec.rb
|
129
131
|
- spec/memcache_spec.rb
|
130
132
|
- spec/mongo_spec.rb
|
133
|
+
- spec/multi_spec.rb
|
131
134
|
- spec/mysql2_spec.rb
|
132
135
|
- spec/redis_spec.rb
|
133
136
|
- spec/remcached_spec.rb
|
134
137
|
- spec/synchrony_spec.rb
|
135
138
|
- spec/tcpsocket_spec.rb
|
139
|
+
- spec/thread_spec.rb
|
136
140
|
- spec/timer_spec.rb
|
141
|
+
has_rdoc:
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
# AR adapter for using a fibered mysql2 connection with EM
|
4
|
-
# This adapter should be used within Thin or Unicorn with the rack-fiber_pool middleware.
|
5
|
-
# Just update your database.yml's adapter to be 'em_mysql2'
|
6
|
-
|
7
|
-
require 'active_record/connection_adapters/abstract_adapter'
|
8
|
-
require 'active_record/connection_adapters/mysql2_adapter'
|
9
|
-
|
10
|
-
module ActiveRecord
|
11
|
-
class Base
|
12
|
-
def self.em_mysql2_connection(config)
|
13
|
-
client = Mysql2::EM::Client.new(config.symbolize_keys)
|
14
|
-
options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0]
|
15
|
-
ConnectionAdapters::Mysql2Adapter.new(client, logger, options, config)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,132 +0,0 @@
|
|
1
|
-
# Necessary monkeypatching to make AR fiber-friendly.
|
2
|
-
|
3
|
-
module ActiveRecord
|
4
|
-
module ConnectionAdapters
|
5
|
-
|
6
|
-
def self.fiber_pools
|
7
|
-
@fiber_pools ||= []
|
8
|
-
end
|
9
|
-
def self.register_fiber_pool(fp)
|
10
|
-
fiber_pools << fp
|
11
|
-
end
|
12
|
-
|
13
|
-
class FiberedMonitor
|
14
|
-
class Queue
|
15
|
-
def initialize
|
16
|
-
@queue = []
|
17
|
-
end
|
18
|
-
|
19
|
-
def wait(timeout)
|
20
|
-
t = timeout || 5
|
21
|
-
fiber = Fiber.current
|
22
|
-
x = EM::Timer.new(t) do
|
23
|
-
@queue.delete(fiber)
|
24
|
-
fiber.resume(false)
|
25
|
-
end
|
26
|
-
@queue << fiber
|
27
|
-
Fiber.yield.tap do
|
28
|
-
x.cancel
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def signal
|
33
|
-
fiber = @queue.pop
|
34
|
-
fiber.resume(true) if fiber
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def synchronize
|
39
|
-
yield
|
40
|
-
end
|
41
|
-
|
42
|
-
def new_cond
|
43
|
-
Queue.new
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# ActiveRecord's connection pool is based on threads. Since we are working
|
48
|
-
# with EM and a single thread, multiple fiber design, we need to provide
|
49
|
-
# our own connection pool that keys off of Fiber.current so that different
|
50
|
-
# fibers running in the same thread don't try to use the same connection.
|
51
|
-
class ConnectionPool
|
52
|
-
def initialize(spec)
|
53
|
-
@spec = spec
|
54
|
-
|
55
|
-
# The cache of reserved connections mapped to threads
|
56
|
-
@reserved_connections = {}
|
57
|
-
|
58
|
-
# The mutex used to synchronize pool access
|
59
|
-
@connection_mutex = FiberedMonitor.new
|
60
|
-
@queue = @connection_mutex.new_cond
|
61
|
-
|
62
|
-
# default 5 second timeout unless on ruby 1.9
|
63
|
-
@timeout = spec.config[:wait_timeout] || 5
|
64
|
-
|
65
|
-
# default max pool size to 5
|
66
|
-
@size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
|
67
|
-
|
68
|
-
@connections = []
|
69
|
-
@checked_out = []
|
70
|
-
@automatic_reconnect = true
|
71
|
-
@tables = {}
|
72
|
-
|
73
|
-
@columns = Hash.new do |h, table_name|
|
74
|
-
h[table_name] = with_connection do |conn|
|
75
|
-
|
76
|
-
# Fetch a list of columns
|
77
|
-
conn.columns(table_name, "#{table_name} Columns").tap do |columns|
|
78
|
-
|
79
|
-
# set primary key information
|
80
|
-
columns.each do |column|
|
81
|
-
column.primary = column.name == primary_keys[table_name]
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
@columns_hash = Hash.new do |h, table_name|
|
88
|
-
h[table_name] = Hash[columns[table_name].map { |col|
|
89
|
-
[col.name, col]
|
90
|
-
}]
|
91
|
-
end
|
92
|
-
|
93
|
-
@primary_keys = Hash.new do |h, table_name|
|
94
|
-
h[table_name] = with_connection do |conn|
|
95
|
-
table_exists?(table_name) ? conn.primary_key(table_name) : 'id'
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def clear_stale_cached_connections!
|
101
|
-
cache = @reserved_connections
|
102
|
-
keys = Set.new(cache.keys)
|
103
|
-
|
104
|
-
ActiveRecord::ConnectionAdapters.fiber_pools.each do |pool|
|
105
|
-
pool.busy_fibers.each_pair do |object_id, fiber|
|
106
|
-
keys.delete(object_id)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
keys.each do |key|
|
111
|
-
next unless cache.has_key?(key)
|
112
|
-
checkin cache[key]
|
113
|
-
cache.delete(key)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
private
|
118
|
-
|
119
|
-
def current_connection_id #:nodoc:
|
120
|
-
Fiber.current.object_id
|
121
|
-
end
|
122
|
-
|
123
|
-
def checkout_and_verify(c)
|
124
|
-
@checked_out << c
|
125
|
-
c.run_callbacks :checkout
|
126
|
-
c.verify!
|
127
|
-
c
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
end
|
132
|
-
end
|