green 0.1 → 0.1.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.lock +6 -6
- data/green.gemspec +7 -3
- data/lib/green-em.rb +24 -0
- data/lib/green-em/em-http.rb +8 -1
- data/lib/green-em/tarantool.rb +0 -0
- data/lib/green.rb +13 -4
- data/lib/green/connection_pool.rb +51 -49
- data/lib/green/hub.rb +14 -3
- data/lib/green/hub/em.rb +4 -3
- data/lib/green/hub/nio4r.rb +5 -5
- data/lib/green/semaphore.rb +1 -1
- data/spec/green/activerecord_spec.rb +99 -99
- data/spec/green/connection_pool_spec.rb +3 -4
- data/spec/green/group_spec.rb +23 -1
- data/spec/green/mysql2_spec.rb +2 -2
- data/spec/green_spec.rb +8 -1
- metadata +5 -3
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
green (0.1)
|
4
|
+
green (0.1.1)
|
5
5
|
kgio (= 2.7.4)
|
6
6
|
|
7
7
|
GEM
|
@@ -23,15 +23,15 @@ GEM
|
|
23
23
|
ansi (1.4.2)
|
24
24
|
arel (3.0.2)
|
25
25
|
builder (3.0.0)
|
26
|
-
columnize (0.3.
|
26
|
+
columnize (0.3.6)
|
27
27
|
cookiejar (0.3.0)
|
28
|
-
debugger (1.
|
28
|
+
debugger (1.2.2)
|
29
29
|
columnize (>= 0.3.1)
|
30
30
|
debugger-linecache (~> 1.1.1)
|
31
|
-
debugger-ruby_core_source (~> 1.1.
|
32
|
-
debugger-linecache (1.1.
|
31
|
+
debugger-ruby_core_source (~> 1.1.5)
|
32
|
+
debugger-linecache (1.1.2)
|
33
33
|
debugger-ruby_core_source (>= 1.1.1)
|
34
|
-
debugger-ruby_core_source (1.1.
|
34
|
+
debugger-ruby_core_source (1.1.5)
|
35
35
|
em-http-request (1.0.2)
|
36
36
|
addressable (>= 2.2.3)
|
37
37
|
cookiejar
|
data/green.gemspec
CHANGED
@@ -4,8 +4,10 @@ Gem::Specification.new do |s|
|
|
4
4
|
s.rubygems_version = '1.3.5'
|
5
5
|
|
6
6
|
s.name = 'green'
|
7
|
-
|
8
|
-
s.
|
7
|
+
|
8
|
+
s.version = '0.1.1'
|
9
|
+
s.date = '2013-01-28'
|
10
|
+
|
9
11
|
s.rubyforge_project = 'green'
|
10
12
|
|
11
13
|
s.summary = "Cooperative multitasking fo Ruby"
|
@@ -30,7 +32,9 @@ Gem::Specification.new do |s|
|
|
30
32
|
app.ru
|
31
33
|
green.gemspec
|
32
34
|
lib/active_record/connection_adapters/green_mysql2_adapter.rb
|
35
|
+
lib/green-em.rb
|
33
36
|
lib/green-em/em-http.rb
|
37
|
+
lib/green-em/tarantool.rb
|
34
38
|
lib/green.rb
|
35
39
|
lib/green/activerecord.rb
|
36
40
|
lib/green/connection_pool.rb
|
@@ -64,4 +68,4 @@ Gem::Specification.new do |s|
|
|
64
68
|
## Test files will be grabbed from the file list. Make sure the path glob
|
65
69
|
## matches what you actually use.
|
66
70
|
s.test_files = s.files.select { |path| path =~ /^spec\/.*_spec\.rb/ }
|
67
|
-
end
|
71
|
+
end
|
data/lib/green-em.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'green'
|
2
|
+
class Green
|
3
|
+
module EM
|
4
|
+
extend self
|
5
|
+
def sync(deferrable, params = {})
|
6
|
+
g = Green.current
|
7
|
+
deferrable.callback { |*args| g.switch(*get_args(args, params[:errback_args])) }
|
8
|
+
deferrable.errback { |*args| g.throw(get_args(args, params[:errback_args]).first) }
|
9
|
+
Green.hub.wait { deferrable.green_cancel }
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_args(args, proc_args)
|
13
|
+
case proc_args
|
14
|
+
when Proc
|
15
|
+
proc.call(*args)
|
16
|
+
when nil
|
17
|
+
args
|
18
|
+
else
|
19
|
+
proc_args
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
data/lib/green-em/em-http.rb
CHANGED
@@ -3,6 +3,7 @@ begin
|
|
3
3
|
rescue LoadError => error
|
4
4
|
raise "Missing EM-Synchrony dependency: gem install em-http-request"
|
5
5
|
end
|
6
|
+
require 'green-em'
|
6
7
|
|
7
8
|
module EventMachine
|
8
9
|
class HTTPException < RuntimeError; end
|
@@ -11,6 +12,7 @@ module EventMachine
|
|
11
12
|
class_eval %[
|
12
13
|
alias :a#{type} :#{type}
|
13
14
|
def #{type}(options = {}, &blk)
|
15
|
+
<<<<<<< HEAD
|
14
16
|
g = Green.current
|
15
17
|
conn = setup_request(:#{type}, options, &blk)
|
16
18
|
if conn.error.nil?
|
@@ -18,6 +20,11 @@ module EventMachine
|
|
18
20
|
conn.errback { g.throw(HTTPException.new) }
|
19
21
|
|
20
22
|
Green.hub.wait { conn.green_cancel }
|
23
|
+
=======
|
24
|
+
conn = setup_request(:"#{type}", options, &blk)
|
25
|
+
if conn.error.nil?
|
26
|
+
Green::EM.sync conn, callback_args: [conn], errback_args: [HTTPException.new(conn)]
|
27
|
+
>>>>>>> - Green::EM.sync
|
21
28
|
else
|
22
29
|
raise HTTPException.new
|
23
30
|
end
|
@@ -25,4 +32,4 @@ module EventMachine
|
|
25
32
|
]
|
26
33
|
end
|
27
34
|
end
|
28
|
-
end
|
35
|
+
end
|
File without changes
|
data/lib/green.rb
CHANGED
@@ -3,7 +3,8 @@ require 'pp'
|
|
3
3
|
require 'thread'
|
4
4
|
|
5
5
|
class Green
|
6
|
-
VERSION = "0.1"
|
6
|
+
VERSION = "0.1.1"
|
7
|
+
|
7
8
|
|
8
9
|
module GreenMethods
|
9
10
|
def switch(*args)
|
@@ -33,6 +34,12 @@ class Green
|
|
33
34
|
def []=(name, val)
|
34
35
|
locals[name] = val
|
35
36
|
end
|
37
|
+
|
38
|
+
def schedule(*args)
|
39
|
+
Green.hub.callback { self.switch(*args) }
|
40
|
+
end
|
41
|
+
|
42
|
+
alias call schedule
|
36
43
|
end
|
37
44
|
|
38
45
|
class Proxy
|
@@ -112,6 +119,10 @@ class Green
|
|
112
119
|
def list
|
113
120
|
list_hash.values
|
114
121
|
end
|
122
|
+
|
123
|
+
def init
|
124
|
+
hub
|
125
|
+
end
|
115
126
|
end
|
116
127
|
|
117
128
|
class GreenError < StandardError; end
|
@@ -136,11 +147,9 @@ class Green
|
|
136
147
|
begin
|
137
148
|
res = yield
|
138
149
|
rescue GreenKill => e
|
139
|
-
rescue => e
|
140
|
-
Green.main.throw e
|
141
150
|
end
|
142
151
|
@alive = false
|
143
|
-
@callbacks.each { |c|
|
152
|
+
@callbacks.each { |c|
|
144
153
|
c.call(res)
|
145
154
|
}
|
146
155
|
Green.list_hash.delete self
|
@@ -1,72 +1,74 @@
|
|
1
1
|
class Green
|
2
2
|
class ConnectionPool
|
3
|
-
|
3
|
+
class Proxy < BasicObject
|
4
|
+
def initialize(pool)
|
5
|
+
@pool = pool
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_missing(method, *args, &blk)
|
9
|
+
@pool.execute do |conn|
|
10
|
+
conn.__send__(method, *args, &blk)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
4
14
|
|
5
|
-
|
6
|
-
|
15
|
+
attr_accessor :available, :pending, :disconnect_class, :new_block
|
16
|
+
|
17
|
+
def initialize(opts = {}, &block)
|
7
18
|
@available = [] # pool of free connections
|
8
19
|
@pending = [] # pending reservations (FIFO)
|
9
20
|
|
21
|
+
@disconnect_class = opts[:disconnect_class]
|
22
|
+
@new_block = block
|
10
23
|
opts[:size].times do
|
11
|
-
@available.push(
|
24
|
+
@available.push(@new_block.call)
|
12
25
|
end
|
13
26
|
end
|
14
27
|
|
15
|
-
# Choose first available connection and pass it to the supplied
|
16
|
-
# block. This will block indefinitely until there is an available
|
17
|
-
# connection to service the request.
|
18
28
|
def execute
|
19
|
-
g = Green.current
|
20
29
|
begin
|
21
|
-
conn = acquire
|
30
|
+
conn = acquire
|
22
31
|
yield conn
|
32
|
+
rescue => e
|
33
|
+
if @disconnect_class && e.is_a?(@disconnect_class)
|
34
|
+
disconnected = true
|
35
|
+
@available << @new_block.call
|
36
|
+
else
|
37
|
+
raise
|
38
|
+
end
|
23
39
|
ensure
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
# Acquire a lock on a connection and assign it to executing fiber
|
31
|
-
# - if connection is available, pass it back to the calling block
|
32
|
-
# - if pool is full, yield the current fiber until connection is available
|
33
|
-
def acquire(green)
|
34
|
-
if conn = @available.pop
|
35
|
-
@reserved[green.object_id] = conn
|
36
|
-
conn
|
40
|
+
if disconnected
|
41
|
+
try_next
|
37
42
|
else
|
38
|
-
|
39
|
-
|
40
|
-
acquire(green)
|
43
|
+
release conn
|
44
|
+
try_next
|
41
45
|
end
|
42
46
|
end
|
47
|
+
end
|
43
48
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
def release(green)
|
48
|
-
conn = @reserved.delete(green.object_id)
|
49
|
-
@available.push(conn)
|
49
|
+
def proxy
|
50
|
+
@proxy ||= Proxy.new(self)
|
51
|
+
end
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
-
|
53
|
+
def acquire
|
54
|
+
g = Green.current
|
55
|
+
if conn = @available.pop
|
56
|
+
conn
|
57
|
+
else
|
58
|
+
@pending.push g
|
59
|
+
Green.hub.wait { @pending.delete g }
|
60
|
+
acquire
|
54
61
|
end
|
62
|
+
end
|
55
63
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
# data is available, or request is complete)
|
64
|
-
#
|
65
|
-
def method_missing(method, *args, &blk)
|
66
|
-
execute do |conn|
|
67
|
-
conn.__send__(method, *args, &blk)
|
68
|
-
end
|
64
|
+
def release(conn)
|
65
|
+
@available.push conn
|
66
|
+
end
|
67
|
+
|
68
|
+
def try_next
|
69
|
+
if pending = @pending.shift
|
70
|
+
Green.hub.callback { pending.switch }
|
69
71
|
end
|
72
|
+
end
|
70
73
|
end
|
71
|
-
|
72
|
-
end
|
74
|
+
end
|
data/lib/green/hub.rb
CHANGED
@@ -2,14 +2,25 @@ class Green
|
|
2
2
|
class Hub
|
3
3
|
attr_reader :g
|
4
4
|
def initialize
|
5
|
+
|
6
|
+
start_hub
|
7
|
+
end
|
8
|
+
|
9
|
+
def start_hub
|
5
10
|
c = Green.current
|
6
|
-
callback { c.switch }
|
11
|
+
callback { c.switch }
|
7
12
|
@g = Green.new do
|
8
|
-
|
13
|
+
begin
|
14
|
+
run
|
15
|
+
rescue => e
|
16
|
+
start_hub
|
17
|
+
raise
|
18
|
+
end
|
9
19
|
end
|
10
20
|
g.switch
|
11
21
|
end
|
12
22
|
|
23
|
+
|
13
24
|
def switch
|
14
25
|
g.switch
|
15
26
|
end
|
@@ -48,4 +59,4 @@ class Green
|
|
48
59
|
raise "override"
|
49
60
|
end
|
50
61
|
end
|
51
|
-
end
|
62
|
+
end
|
data/lib/green/hub/em.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
require 'eventmachine'
|
2
3
|
|
3
4
|
class ::EM::Timer
|
@@ -20,7 +21,7 @@ class Green
|
|
20
21
|
class SocketWaiter < Green::SocketWaiter
|
21
22
|
class Handler < ::EM::Connection
|
22
23
|
attr_accessor :green
|
23
|
-
def notify_readable
|
24
|
+
def notify_readable
|
24
25
|
green.switch
|
25
26
|
end
|
26
27
|
|
@@ -55,7 +56,7 @@ class Green
|
|
55
56
|
end
|
56
57
|
# если мы запускаем приложение внутри thin или rainbows с EM, то значит мы уже внутри EM-реактора, а hub должен переключиться в main тред.
|
57
58
|
def run
|
58
|
-
if ::EM.reactor_running?
|
59
|
+
if ::EM.reactor_running?
|
59
60
|
loop do
|
60
61
|
Green.main.switch
|
61
62
|
end
|
@@ -81,4 +82,4 @@ class Green
|
|
81
82
|
end
|
82
83
|
end
|
83
84
|
end
|
84
|
-
end
|
85
|
+
end
|
data/lib/green/hub/nio4r.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'nio'
|
2
|
-
require 'algorithms'
|
3
|
-
|
4
1
|
class Green
|
5
2
|
class Hub
|
6
3
|
class Nio4r < Hub
|
@@ -56,12 +53,15 @@ class Green
|
|
56
53
|
|
57
54
|
attr_reader :callbacks, :timers, :cancel_timers
|
58
55
|
def initialize(*args)
|
56
|
+
require 'nio'
|
57
|
+
require 'algorithms'
|
58
|
+
|
59
59
|
@callbacks = []
|
60
60
|
@timers = Containers::MinHeap.new
|
61
61
|
@cancel_timers = {}
|
62
62
|
super
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
def reactor_running?
|
66
66
|
@reactor_running
|
67
67
|
end
|
@@ -105,7 +105,7 @@ class Green
|
|
105
105
|
i += 1
|
106
106
|
end
|
107
107
|
ensure
|
108
|
-
@callbacks[0...0] = jobs[i..-1] if i < jobs.size
|
108
|
+
@callbacks[0...0] = jobs[(i + 1)..-1] if i < jobs.size
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
data/lib/green/semaphore.rb
CHANGED
@@ -1,100 +1,100 @@
|
|
1
|
-
# DO NOT WORK
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
require "green/activerecord"
|
5
|
-
require 'green/group'
|
6
|
-
|
7
|
-
|
8
|
-
# create database widgets;
|
9
|
-
# use widgets;
|
10
|
-
# create table widgets (
|
11
|
-
# id INT NOT NULL AUTO_INCREMENT,
|
12
|
-
# title varchar(255),
|
13
|
-
# PRIMARY KEY (`id`)
|
14
|
-
# );
|
15
|
-
|
16
|
-
class Widget < ActiveRecord::Base; end;
|
17
|
-
|
18
|
-
describe Green::ActiveRecord do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
1
|
+
# # DO NOT WORK
|
2
|
+
|
3
|
+
# require "spec_helper"
|
4
|
+
# require "green/activerecord"
|
5
|
+
# require 'green/group'
|
6
|
+
|
7
|
+
|
8
|
+
# # create database widgets;
|
9
|
+
# # use widgets;
|
10
|
+
# # create table widgets (
|
11
|
+
# # id INT NOT NULL AUTO_INCREMENT,
|
12
|
+
# # title varchar(255),
|
13
|
+
# # PRIMARY KEY (`id`)
|
14
|
+
# # );
|
15
|
+
|
16
|
+
# class Widget < ActiveRecord::Base; end;
|
17
|
+
|
18
|
+
# describe Green::ActiveRecord do
|
19
|
+
# DELAY = 0.25
|
20
|
+
# QUERY = "SELECT sleep(#{DELAY})"
|
21
|
+
|
22
|
+
# def establish_connection
|
23
|
+
# # ActiveRecord::Base.logger = Logger.new STDOUT
|
24
|
+
# ActiveRecord::Base.establish_connection(
|
25
|
+
# :adapter => 'green_mysql2',
|
26
|
+
# :database => 'widgets',
|
27
|
+
# :username => 'root',
|
28
|
+
# :pool => 50
|
29
|
+
# )
|
30
|
+
# Widget.delete_all
|
31
|
+
# end
|
32
|
+
|
33
|
+
# before do
|
34
|
+
# establish_connection
|
35
|
+
# end
|
36
|
+
|
37
|
+
# after do
|
38
|
+
# ActiveRecord::Base.connection_pool.disconnect!
|
39
|
+
# end
|
40
|
+
|
41
|
+
# it "should establish AR connection" do
|
42
|
+
# result = Widget.find_by_sql(QUERY)
|
43
|
+
# result.size.must_equal 1
|
44
|
+
# end
|
45
|
+
|
46
|
+
# it "should fire sequential, synchronous requests within single green" do
|
47
|
+
# start = Time.now.to_f
|
48
|
+
# res = []
|
49
|
+
|
50
|
+
# res.push Widget.find_by_sql(QUERY)
|
51
|
+
# res.push Widget.find_by_sql(QUERY)
|
52
|
+
|
53
|
+
# (Time.now.to_f - start.to_f).must_be_within_delta DELAY * res.size, DELAY * res.size * 0.15
|
54
|
+
# res.size.must_equal 2
|
55
|
+
# end
|
56
|
+
|
57
|
+
# # it "should fire 100 requests" do
|
58
|
+
# # pool = Green::Pool.new size: 40, klass: Green::ActiveRecord
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
end
|
60
|
+
# # 100.times do
|
61
|
+
# # pool.spawn do
|
62
|
+
# # widget = Widget.create title: 'hi'
|
63
|
+
# # widget.update_attributes title: 'hello'
|
64
|
+
# # end
|
65
|
+
# # end
|
66
|
+
# # pool.join
|
67
|
+
# # end
|
68
|
+
|
69
|
+
# it "should create widget" do
|
70
|
+
# Widget.create
|
71
|
+
# Widget.create
|
72
|
+
# Widget.count.must_equal 2
|
73
|
+
# end
|
74
|
+
|
75
|
+
# it "should update widget" do
|
76
|
+
# widget = Widget.create title: 'hi'
|
77
|
+
# widget.update_attributes title: 'hello'
|
78
|
+
# Widget.find(widget.id).title.must_equal 'hello'
|
79
|
+
# end
|
80
|
+
|
81
|
+
# # describe "transactions" do
|
82
|
+
# # it "should work properly" do
|
83
|
+
# # pool = Green::Pool.new size: 40, klass: Green::ActiveRecord
|
84
|
+
# # 50.times do |i|
|
85
|
+
# # pool.spawn do
|
86
|
+
# # widget = Widget.create title: "hello"
|
87
|
+
# # ActiveRecord::Base.transaction do
|
88
|
+
# # widget.update_attributes title: "hi#{i}"
|
89
|
+
# # raise ActiveRecord::Rollback
|
90
|
+
# # end
|
91
|
+
# # end
|
92
|
+
# # end
|
93
|
+
# # pool.join
|
94
|
+
# # Widget.all.each do |widget|
|
95
|
+
# # widget.title.must_equal 'hello'
|
96
|
+
# # end
|
97
|
+
# # end
|
98
|
+
# # end
|
99
|
+
|
100
|
+
# end
|
@@ -8,8 +8,7 @@ QUERY = "select sleep(#{DELAY})"
|
|
8
8
|
|
9
9
|
describe Green::ConnectionPool do
|
10
10
|
|
11
|
-
|
12
|
-
let(:pool) { Green::ConnectionPool.new(size: size) { Green::Mysql2::Client.new } }
|
11
|
+
let(:pool) { Green::ConnectionPool.new(size: size) { Green::Mysql2::Client.new }.proxy }
|
13
12
|
|
14
13
|
describe "pool size is exceeded" do
|
15
14
|
let(:size) { 1 }
|
@@ -17,7 +16,7 @@ describe Green::ConnectionPool do
|
|
17
16
|
start = Time.now.to_f
|
18
17
|
|
19
18
|
g = Green::Group.new
|
20
|
-
res = []
|
19
|
+
res = []
|
21
20
|
g.spawn { res << pool.query(QUERY) }
|
22
21
|
g.spawn { res << pool.query(QUERY) }
|
23
22
|
g.join
|
@@ -42,4 +41,4 @@ describe Green::ConnectionPool do
|
|
42
41
|
res.size.must_equal 2
|
43
42
|
end
|
44
43
|
end
|
45
|
-
end
|
44
|
+
end
|
data/spec/green/group_spec.rb
CHANGED
@@ -39,7 +39,8 @@ end
|
|
39
39
|
describe Green::Pool do
|
40
40
|
let(:e1) { Green::Event.new }
|
41
41
|
let(:e2) { Green::Event.new }
|
42
|
-
let(:
|
42
|
+
let(:size) { 1 }
|
43
|
+
let(:p) { Green::Pool.new size: size }
|
43
44
|
|
44
45
|
it "should wait each task" do
|
45
46
|
result = ""
|
@@ -49,6 +50,27 @@ describe Green::Pool do
|
|
49
50
|
result.must_equal "fizbaz"
|
50
51
|
end
|
51
52
|
|
53
|
+
describe "spawn attack" do
|
54
|
+
let(:size) { 10 }
|
55
|
+
it "should work correctly" do
|
56
|
+
i = 0
|
57
|
+
100.times { p.spawn { i += 1 } }
|
58
|
+
p.join
|
59
|
+
i.must_equal 100
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "with random timer" do
|
63
|
+
it "should work correctly" do
|
64
|
+
i = 0
|
65
|
+
100.times { p.spawn { Green.sleep(rand); i += 1 } }
|
66
|
+
p.join
|
67
|
+
i.must_equal 100
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
|
52
74
|
# ugly test :(
|
53
75
|
it "should block after limit" do
|
54
76
|
i = 0
|
data/spec/green/mysql2_spec.rb
CHANGED
@@ -30,7 +30,7 @@ describe Green::Mysql2 do
|
|
30
30
|
it "should fire simultaneous requests via pool" do
|
31
31
|
db = Green::ConnectionPool.new(size: 2) do
|
32
32
|
Green::Mysql2::Client.new
|
33
|
-
end
|
33
|
+
end.proxy
|
34
34
|
|
35
35
|
start = Time.now.to_f
|
36
36
|
res = []
|
@@ -49,4 +49,4 @@ describe Green::Mysql2 do
|
|
49
49
|
db.query("SELECT * FROM i_hope_this_table_does_not_exist;")
|
50
50
|
}.must_raise(Mysql2::Error)
|
51
51
|
end
|
52
|
-
end
|
52
|
+
end
|
data/spec/green_spec.rb
CHANGED
@@ -34,4 +34,11 @@ describe Green do
|
|
34
34
|
(Time.now - t).must_be :<, 0.1
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
|
+
describe "exceptions" do
|
39
|
+
it "should raise exception from reactor to main fiber" do
|
40
|
+
Green.hub.callback { raise "ololo" }
|
41
|
+
proc { Green.sleep(0.1) }.must_raise RuntimeError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: green
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: kgio
|
@@ -41,7 +41,9 @@ files:
|
|
41
41
|
- app.ru
|
42
42
|
- green.gemspec
|
43
43
|
- lib/active_record/connection_adapters/green_mysql2_adapter.rb
|
44
|
+
- lib/green-em.rb
|
44
45
|
- lib/green-em/em-http.rb
|
46
|
+
- lib/green-em/tarantool.rb
|
45
47
|
- lib/green.rb
|
46
48
|
- lib/green/activerecord.rb
|
47
49
|
- lib/green/connection_pool.rb
|
@@ -84,7 +86,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
86
|
version: '0'
|
85
87
|
segments:
|
86
88
|
- 0
|
87
|
-
hash:
|
89
|
+
hash: 4284378326440113504
|
88
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
91
|
none: false
|
90
92
|
requirements:
|