tarantool 0.3.0.7 → 0.4.2.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 +2 -3
- data/README.md +90 -30
- data/Rakefile +6 -1
- data/lib/tarantool.rb +93 -18
- data/lib/tarantool/base_record.rb +97 -10
- data/lib/tarantool/block_db.rb +104 -6
- data/lib/tarantool/callback_db.rb +7 -0
- data/lib/tarantool/core-ext.rb +24 -8
- data/lib/tarantool/em_db.rb +189 -20
- data/lib/tarantool/exceptions.rb +4 -0
- data/lib/tarantool/fiber_db.rb +15 -1
- data/lib/tarantool/light_record.rb +17 -0
- data/lib/tarantool/query.rb +15 -9
- data/lib/tarantool/record/select.rb +21 -3
- data/lib/tarantool/request.rb +130 -43
- data/lib/tarantool/response.rb +70 -7
- data/lib/tarantool/serializers.rb +26 -5
- data/lib/tarantool/serializers/ber_array.rb +14 -0
- data/lib/tarantool/shards_support.rb +204 -0
- data/lib/tarantool/space_array.rb +38 -13
- data/lib/tarantool/space_hash.rb +49 -27
- data/lib/tarantool/util.rb +96 -10
- data/lib/tarantool/version.rb +2 -1
- data/test/helper.rb +154 -4
- data/test/{tarant/init.lua → init.lua} +0 -0
- data/test/run_all.rb +2 -2
- data/test/shared_record.rb +59 -0
- data/test/shared_replicated_shard.rb +1018 -0
- data/test/shared_reshard.rb +380 -0
- data/test/tarantool.cfg +2 -0
- data/test/test_light_record.rb +2 -0
- data/test/test_light_record_callback.rb +92 -0
- data/test/test_query_block.rb +1 -0
- data/test/test_query_fiber.rb +1 -0
- data/test/test_reshard_block.rb +7 -0
- data/test/test_reshard_fiber.rb +11 -0
- data/test/test_shard_replication_block.rb +7 -0
- data/test/test_shard_replication_fiber.rb +11 -0
- data/test/test_space_array_block.rb +1 -0
- data/test/test_space_array_callback.rb +50 -121
- data/test/test_space_array_callback_nodef.rb +39 -96
- data/test/test_space_array_fiber.rb +1 -0
- data/test/test_space_hash_block.rb +1 -0
- data/test/test_space_hash_fiber.rb +1 -0
- metadata +54 -17
- data/lib/tarantool/record.rb +0 -164
- data/test/box.pid +0 -1
- data/test/tarantool.log +0 -6
- data/test/tarantool_repl.cfg +0 -53
- data/test/test_record.rb +0 -88
- data/test/test_record_composite_pk.rb +0 -77
data/lib/tarantool/space_hash.rb
CHANGED
@@ -5,9 +5,10 @@ require 'tarantool/core-ext'
|
|
5
5
|
|
6
6
|
module Tarantool
|
7
7
|
class SpaceHash
|
8
|
+
include CommonSpace
|
8
9
|
include Request
|
9
10
|
|
10
|
-
def initialize(tarantool, space_no, fields_def, indexes)
|
11
|
+
def initialize(tarantool, space_no, fields_def, indexes, shard_fields = nil, shard_proc = nil)
|
11
12
|
@tarantool = tarantool
|
12
13
|
@space_no = space_no
|
13
14
|
|
@@ -46,16 +47,17 @@ module Tarantool
|
|
46
47
|
@index_fields = [*indexes].map{|ind| [*ind].map{|fld| fld.to_sym}.freeze}.freeze
|
47
48
|
@indexes = _map_indexes(@index_fields)
|
48
49
|
@translators = [TranslateToHash.new(@field_names - [:_tail], @tail_size)].freeze
|
49
|
-
end
|
50
50
|
|
51
|
-
|
52
|
-
@
|
51
|
+
@shard_fields = [*(shard_fields || @index_fields[0])]
|
52
|
+
@shard_positions = @shard_fields.map{|name| @field_to_pos[name]}
|
53
|
+
_init_shard_vars(shard_proc)
|
53
54
|
end
|
54
55
|
|
55
56
|
def with_translator(cb = nil, &block)
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
clone.instance_exec do
|
58
|
+
@translators += [cb || block]
|
59
|
+
self
|
60
|
+
end
|
59
61
|
end
|
60
62
|
|
61
63
|
def _map_indexes(indexes)
|
@@ -66,10 +68,6 @@ module Tarantool
|
|
66
68
|
end.freeze
|
67
69
|
end
|
68
70
|
|
69
|
-
def _send_request(type, body, cb)
|
70
|
-
@tarantool._send_request(type, body, cb)
|
71
|
-
end
|
72
|
-
|
73
71
|
def select_cb(keys, offset, limit, cb)
|
74
72
|
index_names = Hash === keys ? keys.keys : keys.first.keys
|
75
73
|
index_no = @index_fields.index{|fields|
|
@@ -102,7 +100,9 @@ module Tarantool
|
|
102
100
|
end
|
103
101
|
end
|
104
102
|
|
105
|
-
|
103
|
+
shard_nums = _get_shard_nums { _detect_shards_for_keys(keys, index_no) }
|
104
|
+
|
105
|
+
_select(@space_no, index_no, offset, limit, keys, cb, @field_types, index_types, shard_nums, @translators)
|
106
106
|
end
|
107
107
|
|
108
108
|
def all_cb(keys, cb, opts = {})
|
@@ -114,15 +114,17 @@ module Tarantool
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def all_by_pks_cb(keys, cb, opts={})
|
117
|
-
keys = [*keys].map{|key| _prepare_pk(key)}
|
117
|
+
keys = (Hash === keys ? [keys] : [*keys]).map{|key| _prepare_pk(key)}
|
118
|
+
shard_nums = _get_shard_nums{ _detect_shards_for_keys(keys, 0) }
|
118
119
|
_select(@space_no, 0,
|
119
120
|
opts[:offset] || 0, opts[:limit] || -1,
|
120
|
-
keys, cb, @field_types, @indexes[0], @translators)
|
121
|
+
keys, cb, @field_types, @indexes[0], shard_nums, @translators)
|
121
122
|
end
|
122
123
|
|
123
|
-
def by_pk_cb(
|
124
|
-
|
125
|
-
|
124
|
+
def by_pk_cb(pk, cb)
|
125
|
+
pk = _prepare_pk(pk)
|
126
|
+
shard_nums = _get_shard_nums{ _detect_shards_for_key(pk, 0) }
|
127
|
+
_select(@space_no, 0, 0, :first, [pk], cb, @field_types, @indexes[0], shard_nums, @translators)
|
126
128
|
end
|
127
129
|
|
128
130
|
def _prepare_tuple(tuple)
|
@@ -142,13 +144,30 @@ module Tarantool
|
|
142
144
|
end
|
143
145
|
|
144
146
|
def insert_cb(tuple, cb, opts = {})
|
145
|
-
|
146
|
-
|
147
|
+
tuple = _prepare_tuple(tuple)
|
148
|
+
shard_nums = detect_shard_for_insert(tuple.values_at(*@shard_positions))
|
149
|
+
_insert(@space_no, BOX_ADD, tuple, @field_types, cb, opts[:return_tuple],
|
150
|
+
shard_nums, nil, @translators)
|
147
151
|
end
|
148
152
|
|
149
153
|
def replace_cb(tuple, cb, opts = {})
|
150
|
-
|
151
|
-
|
154
|
+
tuple = _prepare_tuple(tuple)
|
155
|
+
shard_nums = detect_shard(tuple.values_at(*@shard_positions))
|
156
|
+
_insert(@space_no, BOX_REPLACE, tuple, @field_types, cb, opts[:return_tuple],
|
157
|
+
shard_nums, opts.fetch(:in_any_shard, true), @translators)
|
158
|
+
end
|
159
|
+
|
160
|
+
def store_cb(tuple, cb, opts = {})
|
161
|
+
tuple = _prepare_tuple(tuple)
|
162
|
+
shard_nums = _get_shard_nums{
|
163
|
+
if opts.fetch(:to_insert_shard, true)
|
164
|
+
_detect_shard_for_insert(tuple.values_at(*@shard_positions))
|
165
|
+
else
|
166
|
+
_detect_shard(tuple.values_at(*@shard_positions))
|
167
|
+
end
|
168
|
+
}
|
169
|
+
_insert(@space_no, 0, tuple, @field_types, cb, opts[:return_tuple],
|
170
|
+
shard_nums, nil, @translators)
|
152
171
|
end
|
153
172
|
|
154
173
|
def _prepare_pk(pk)
|
@@ -209,13 +228,16 @@ module Tarantool
|
|
209
228
|
)
|
210
229
|
end
|
211
230
|
}
|
212
|
-
|
213
|
-
|
231
|
+
shard_nums = _get_shard_nums{ _detect_shards_for_key(pk, 0) }
|
232
|
+
_update(@space_no, pk, opers, @field_types, @indexes[0], cb, opts[:return_tuple],
|
233
|
+
shard_nums, @translators)
|
214
234
|
end
|
215
235
|
|
216
236
|
def delete_cb(pk, cb, opts = {})
|
217
|
-
|
218
|
-
|
237
|
+
pk = _prepare_pk(pk)
|
238
|
+
shard_nums = _get_shard_nums{ _detect_shards_for_key(pk, 0) }
|
239
|
+
_delete(@space_no, pk, @field_types, @indexes[0], cb, opts[:return_tuple],
|
240
|
+
shard_nums, @translators)
|
219
241
|
end
|
220
242
|
|
221
243
|
def invoke_cb(func_name, values, cb, opts = {})
|
@@ -252,10 +274,10 @@ module Tarantool
|
|
252
274
|
end
|
253
275
|
|
254
276
|
def first_blk(key, &block)
|
255
|
-
|
277
|
+
first_cb(key, block)
|
256
278
|
end
|
257
279
|
|
258
|
-
def select_blk(keys, offset=0, limit
|
280
|
+
def select_blk(keys, offset=0, limit=-1, &block)
|
259
281
|
select_cb(keys, offset, limit, block)
|
260
282
|
end
|
261
283
|
end
|
data/lib/tarantool/util.rb
CHANGED
@@ -1,8 +1,36 @@
|
|
1
1
|
module Tarantool
|
2
2
|
module Util
|
3
3
|
module Packer
|
4
|
+
INT8 = 'C'.freeze
|
5
|
+
INT16 = 'v'.freeze
|
6
|
+
INT32 = 'V'.freeze
|
7
|
+
INT64 = 'Q<'.freeze
|
8
|
+
SINT8 = 'c'.freeze
|
9
|
+
SINT16 = 's<'.freeze
|
10
|
+
SINT32 = 'l<'.freeze
|
11
|
+
SINT64 = 'q<'.freeze
|
12
|
+
MIN_INT = 0
|
13
|
+
MAX_INT64 = 2**64 - 1
|
14
|
+
MAX_INT32 = 2**32 - 1
|
15
|
+
MAX_INT16 = 2**16 - 1
|
16
|
+
MAX_INT8 = 2**8 - 1
|
17
|
+
MAX_SINT64 = 2**63 - 1
|
18
|
+
MAX_SINT32 = 2**31 - 1
|
19
|
+
MAX_SINT16 = 2**15 - 1
|
20
|
+
MAX_SINT8 = 2**7 - 1
|
21
|
+
MIN_SINT64 = -(2**63)
|
22
|
+
MIN_SINT32 = -(2**31)
|
23
|
+
MIN_SINT16 = -(2**15)
|
24
|
+
MIN_SINT8 = -(2**7)
|
4
25
|
private
|
5
26
|
EMPTY = ''.freeze
|
27
|
+
ONE = "\x01".freeze
|
28
|
+
def unpack_int8!(data)
|
29
|
+
int = data.getbyte(0)
|
30
|
+
data[0, 1] = EMPTY
|
31
|
+
int
|
32
|
+
end
|
33
|
+
|
6
34
|
def unpack_int16(data)
|
7
35
|
data.getbyte(0) + data.getbyte(1) * 256
|
8
36
|
end
|
@@ -10,7 +38,7 @@ module Tarantool
|
|
10
38
|
def unpack_int16!(data)
|
11
39
|
int = data.getbyte(0) + data.getbyte(1) * 256
|
12
40
|
data[0, 2] = EMPTY
|
13
|
-
|
41
|
+
int
|
14
42
|
end
|
15
43
|
|
16
44
|
def unpack_int32(int)
|
@@ -26,20 +54,33 @@ module Tarantool
|
|
26
54
|
end
|
27
55
|
|
28
56
|
def unpack_int64!(data)
|
29
|
-
int =
|
30
|
-
data.getbyte(2) * 65536 + data.getbyte(3) * 16777216 +
|
31
|
-
data.getbyte(4) << 32 + data.getbyte(5) << 40 +
|
32
|
-
data.getbyte(6) << 48 + data.getbyte(7) << 56
|
33
|
-
)
|
57
|
+
int = data.unpack(INT64)[0]
|
34
58
|
data[0, 8] = EMPTY
|
35
59
|
int
|
36
60
|
end
|
37
61
|
|
38
62
|
def unpack_int64(data)
|
39
|
-
data.
|
40
|
-
|
41
|
-
|
42
|
-
|
63
|
+
data.unpack(INT64)[0]
|
64
|
+
end
|
65
|
+
|
66
|
+
def unpack_sint8!(data)
|
67
|
+
i = unpack_int8!(data)
|
68
|
+
i - ((i & 128) << 1)
|
69
|
+
end
|
70
|
+
|
71
|
+
def unpack_sint16!(data)
|
72
|
+
i = unpack_int16!(data)
|
73
|
+
i - ((i & 32768) << 1)
|
74
|
+
end
|
75
|
+
|
76
|
+
def unpack_sint32!(data)
|
77
|
+
i = unpack_int32!(data)
|
78
|
+
i - ((i >> 31) << 32)
|
79
|
+
end
|
80
|
+
|
81
|
+
def unpack_sint64!(data)
|
82
|
+
i = unpack_int64!(data)
|
83
|
+
i - ((i >> 63) << 64)
|
43
84
|
end
|
44
85
|
|
45
86
|
def ber_size(int)
|
@@ -64,6 +105,51 @@ module Tarantool
|
|
64
105
|
data[0, pos+1] = EMPTY
|
65
106
|
res
|
66
107
|
end
|
108
|
+
|
109
|
+
def append_int8!(str, int)
|
110
|
+
str << (int & 255)
|
111
|
+
end
|
112
|
+
|
113
|
+
def append_int16!(str, int)
|
114
|
+
str << (int & 255) << ((int>>8) & 255)
|
115
|
+
end
|
116
|
+
|
117
|
+
def append_int32!(str, int)
|
118
|
+
str << (int & 255) << ((int>>8) & 255) <<
|
119
|
+
((int>>16) & 255) << ((int>>24) & 255)
|
120
|
+
end
|
121
|
+
|
122
|
+
def append_int64!(str, int)
|
123
|
+
str << [int].pack(INT64)
|
124
|
+
end
|
125
|
+
|
126
|
+
alias append_sint8! append_int8!
|
127
|
+
alias append_sint16! append_int16!
|
128
|
+
alias append_sint32! append_int32!
|
129
|
+
alias append_sint64! append_int64!
|
130
|
+
|
131
|
+
def append_ber_int8!(str, int)
|
132
|
+
str << 1 << (int & 255)
|
133
|
+
end
|
134
|
+
|
135
|
+
def append_ber_int16!(str, int)
|
136
|
+
str << 2 << (int & 255) << ((int>>8) & 255)
|
137
|
+
end
|
138
|
+
|
139
|
+
def append_ber_int32!(str, int)
|
140
|
+
str << 4 <<
|
141
|
+
(int & 255) << ((int>>8) & 255) <<
|
142
|
+
((int>>16) & 255) << ((int>>24) & 255)
|
143
|
+
end
|
144
|
+
|
145
|
+
def append_ber_int64!(str, int)
|
146
|
+
str << 8 << [int].pack(INT64)
|
147
|
+
end
|
148
|
+
|
149
|
+
alias append_ber_sint8! append_ber_int8!
|
150
|
+
alias append_ber_sint16! append_ber_int16!
|
151
|
+
alias append_ber_sint32! append_ber_int32!
|
152
|
+
alias append_ber_sint64! append_ber_int64!
|
67
153
|
end
|
68
154
|
|
69
155
|
module TailGetter
|
data/lib/tarantool/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'minitest/spec'
|
2
|
-
require 'minitest/autorun'
|
3
2
|
require 'rr'
|
3
|
+
require 'fileutils'
|
4
4
|
|
5
5
|
require 'tarantool'
|
6
6
|
|
@@ -14,6 +14,138 @@ class ArrayPackSerializer
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
module TConf
|
18
|
+
extend FileUtils
|
19
|
+
CONF = {
|
20
|
+
master1: {port: 33013, replica: :imaster},
|
21
|
+
slave1: {port: 34013, replica: :master1},
|
22
|
+
master2: {port: 35013, replica: :imaster},
|
23
|
+
slave2: {port: 36013, replica: :master2},
|
24
|
+
}
|
25
|
+
DIR = File.expand_path('..', __FILE__)
|
26
|
+
def self.fjoin(*args)
|
27
|
+
File.join(*args.map(&:to_s))
|
28
|
+
end
|
29
|
+
def self.dir(name)
|
30
|
+
fjoin(DIR, "tarantool_#{name}")
|
31
|
+
end
|
32
|
+
|
33
|
+
def self._to_master(cfg, conf)
|
34
|
+
cfg.sub!(/^replication_source.*$/, '#\0')
|
35
|
+
end
|
36
|
+
|
37
|
+
def self._to_slave(cfg, master)
|
38
|
+
replica_source = "127.0.0.1:#{CONF.fetch(master)[:port]+3}"
|
39
|
+
cfg.sub!(/^#?replication_source.*$/, "replication_source = \"#{replica_source}\"")
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.prepare(name)
|
43
|
+
conf = CONF.fetch(name)
|
44
|
+
return if conf[:dir]
|
45
|
+
clear(name)
|
46
|
+
dir = dir(name)
|
47
|
+
FileUtils.rm_rf dir
|
48
|
+
mkdir_p(dir)
|
49
|
+
cp fjoin(DIR, 'init.lua'), dir
|
50
|
+
cfg = File.read(fjoin(DIR, 'tarantool.cfg'))
|
51
|
+
cfg.sub!(/(pid_file\s*=\s*)"[^"]*"/, "\\1\"#{fjoin(dir, 'box.pid')}\"")
|
52
|
+
cfg.sub!(/(work_dir\s*=\s*)"[^"]*"/, "\\1\"#{dir}\"")
|
53
|
+
cfg.sub!(/(primary_port\s*=\s*)\d+/, "\\1#{conf[:port]}")
|
54
|
+
cfg.sub!(/(secondary_port\s*=\s*)\d+/, "\\1#{conf[:port]+1}")
|
55
|
+
cfg.sub!(/(admin_port\s*=\s*)\d+/, "\\1#{conf[:port]+2}")
|
56
|
+
cfg.sub!(/(replication_port\s*=\s*)\d+/, "\\1#{conf[:port]+3}")
|
57
|
+
if conf[:replica] == :imaster
|
58
|
+
_to_master(cfg, conf)
|
59
|
+
else
|
60
|
+
_to_slave(cfg, conf[:replica])
|
61
|
+
end
|
62
|
+
File.open(fjoin(dir, 'tarantool.cfg'), 'w'){|f| f.write(cfg)}
|
63
|
+
Dir.chdir(dir) do
|
64
|
+
`tarantool_box --init-storage 2>&1`
|
65
|
+
end
|
66
|
+
conf[:dir] = dir
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.run(name)
|
70
|
+
conf = CONF.fetch(name)
|
71
|
+
return if conf[:pid]
|
72
|
+
prepare(name)
|
73
|
+
Dir.chdir(conf[:dir]) do
|
74
|
+
conf[:pid] = spawn('tarantool_box')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.stop(name)
|
79
|
+
conf = CONF.fetch(name)
|
80
|
+
return unless conf[:pid]
|
81
|
+
Process.kill('INT', conf[:pid])
|
82
|
+
Process.wait2(conf[:pid])
|
83
|
+
conf.delete :pid
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.clear(name)
|
87
|
+
conf = CONF.fetch(name)
|
88
|
+
return unless conf[:dir]
|
89
|
+
stop(name)
|
90
|
+
rm_rf(conf[:dir])
|
91
|
+
conf.delete :dir
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.clear_all
|
95
|
+
CONF.keys.each{|name| clear(name) }
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.reset_and_up_all
|
99
|
+
clear_all
|
100
|
+
CONF.keys.each{|name| run(name) }
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.reset_and_up_masters
|
104
|
+
clear_masters
|
105
|
+
run(:master1)
|
106
|
+
run(:master2)
|
107
|
+
sleep(0.01)
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.clear_masters
|
111
|
+
clear(:master1)
|
112
|
+
clear(:master2)
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.conf(name)
|
116
|
+
{host: '127.0.0.1', port: CONF.fetch(name)[:port]}
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.promote_to_master(name)
|
120
|
+
conf = CONF.fetch(name)
|
121
|
+
raise "#{name} not running" unless conf[:pid]
|
122
|
+
fcfg = fjoin(dir(name), 'tarantool.cfg')
|
123
|
+
cfg = File.read(fcfg)
|
124
|
+
_to_master(cfg, conf)
|
125
|
+
File.open(fcfg, 'w'){|f| f.write(cfg)}
|
126
|
+
sock = TCPSocket.new('127.0.0.1', conf[:port]+2)
|
127
|
+
sock.write("reload configuration\n")
|
128
|
+
3.times{ sock.gets }
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.promote_to_slave(slave, master)
|
132
|
+
clear(slave)
|
133
|
+
prepare(slave)
|
134
|
+
fcfg = fjoin(dir(slave), 'tarantool.cfg')
|
135
|
+
cfg = File.read(fcfg)
|
136
|
+
_to_slave(cfg, master)
|
137
|
+
File.open(fcfg, 'w'){|f| f.write(cfg)}
|
138
|
+
run(slave)
|
139
|
+
end
|
140
|
+
|
141
|
+
at_exit do
|
142
|
+
CONF.keys.each{|name| clear(name)}
|
143
|
+
end
|
144
|
+
end
|
145
|
+
require 'minitest/autorun'
|
146
|
+
TConf.run(:master1)
|
147
|
+
|
148
|
+
|
17
149
|
TCONFIG = { host: '127.0.0.1', port: 33013, admin: 33015 }
|
18
150
|
|
19
151
|
SPACE0 = {
|
@@ -53,7 +185,7 @@ HSPACE3 = {
|
|
53
185
|
module Helper
|
54
186
|
def tarantool_pipe
|
55
187
|
$tarantool_pipe ||= begin
|
56
|
-
cnf = TCONFIG
|
188
|
+
cnf = {port: 33013, admin: 33015} #TCONFIG
|
57
189
|
tarant = %W{tarantool -p #{cnf[:port]} -m #{cnf[:admin]}}
|
58
190
|
tarant = [{}, *tarant, :err => [:child, :out]]
|
59
191
|
IO.popen(tarant, 'w+').tap{|p| p.sync = true}
|
@@ -115,17 +247,35 @@ module Helper
|
|
115
247
|
end
|
116
248
|
end
|
117
249
|
|
250
|
+
def setp(i)
|
251
|
+
@results ||= []
|
252
|
+
proc{|v| @results[i]=v; emstop}
|
253
|
+
end
|
254
|
+
|
255
|
+
def results
|
256
|
+
@results
|
257
|
+
end
|
258
|
+
|
259
|
+
class TimeOut < Exception
|
260
|
+
end
|
118
261
|
def fibrun
|
119
262
|
res = nil
|
120
263
|
EM.run {
|
264
|
+
t = nil
|
121
265
|
f = Fiber.new{
|
122
266
|
begin
|
123
267
|
res = yield
|
124
268
|
ensure
|
125
|
-
EM.next_tick{
|
269
|
+
EM.next_tick{
|
270
|
+
EM.cancel_timer t
|
271
|
+
EM.stop
|
272
|
+
}
|
126
273
|
end
|
127
274
|
}
|
128
275
|
EM.next_tick{ f.resume }
|
276
|
+
t = EM.add_timer(1) {
|
277
|
+
f.resume TimeOut.new
|
278
|
+
}
|
129
279
|
}
|
130
280
|
res
|
131
281
|
end
|
@@ -156,7 +306,7 @@ module MiniTest::Spec::SharedExamples
|
|
156
306
|
end
|
157
307
|
|
158
308
|
def it_behaves_like(desc)
|
159
|
-
class_eval
|
309
|
+
class_eval(&MiniTest::Spec.shared_examples.fetch(desc))
|
160
310
|
end
|
161
311
|
end
|
162
312
|
|