green 0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|