agent 0.9.1 → 0.10.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.
- checksums.yaml +7 -0
- data/.ruby-gemset +1 -0
- data/.travis.yml +16 -0
- data/Gemfile.lock +1 -1
- data/README.md +2 -2
- data/lib/agent/channel.rb +18 -17
- data/lib/agent/pop.rb +2 -4
- data/lib/agent/push.rb +27 -1
- data/lib/agent/queue.rb +1 -1
- data/lib/agent/selector.rb +1 -1
- data/lib/agent/version.rb +1 -1
- data/spec/channel_spec.rb +26 -2
- data/spec/pop_spec.rb +34 -7
- data/spec/push_spec.rb +30 -1
- data/spec/queue_spec.rb +28 -10
- data/spec/selector_spec.rb +22 -4
- data/spec/spec_helper.rb +2 -1
- metadata +15 -20
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 22c5bf05cd41b0171dfce316431f8c42434fa3c1
|
4
|
+
data.tar.gz: 96b5280262b5c4412fd366b6eb897031fa6fd709
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3aa2fcea9b6cf2e55abd8ff3f3139f12f88e8fae2304bddb4d9076ce2d5ba99959fe64cd60291a24433da577aeea104fa6c4fcf7f1d9d9f1e98c88b8037a5b0f
|
7
|
+
data.tar.gz: dbf9aedd6e99043347dba38415f80d7fa166afa1d36abcea0d3c61964d9b09e53f3b5c681e194836b3e7db390166580a749d801a2318ed5076b95a9c05a92618
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
agent
|
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# Agent
|
1
|
+
# Agent [](https://travis-ci.org/igrigorik/agent)
|
2
2
|
|
3
3
|
Agent is an attempt at [Go-like (CSP / pi-calculus) concurrency in Ruby](http://www.igvita.com/2010/12/02/concurrency-with-actors-goroutines-ruby/), but with an additional twist. It is a collection of different [process calculi](http://en.wikipedia.org/wiki/Process_calculus) primitives and patterns, with no specific, idiomatic affiliation to any specific implementation. A few available patterns so far:
|
4
4
|
|
5
5
|
- Goroutines on top of green Ruby threads
|
6
|
-
- Named, Typed,
|
6
|
+
- Named, Typed, Buffered and Unbufferred in-memory "channels"
|
7
7
|
- Selectable "channels"
|
8
8
|
|
9
9
|
This gem is a work in progress, so treat it as such.
|
data/lib/agent/channel.rb
CHANGED
@@ -10,23 +10,20 @@ module Agent
|
|
10
10
|
end
|
11
11
|
|
12
12
|
class Channel
|
13
|
-
|
13
|
+
::Agent::Push::SKIP_MARSHAL_TYPES << ::Agent::Channel
|
14
14
|
|
15
|
-
|
16
|
-
opts = args.last.is_a?(Hash) ? args.pop : {}
|
17
|
-
@type = args.shift
|
18
|
-
@max = args.shift || 0
|
19
|
-
@closed = false
|
20
|
-
@name = opts[:name] || UUID.generate
|
21
|
-
@direction = opts[:direction] || :bidirectional
|
22
|
-
@close_mutex = Mutex.new
|
23
|
-
@queue = Queues.register(@name, @type, @max)
|
24
|
-
end
|
15
|
+
attr_reader :name, :direction, :type, :max, :queue
|
25
16
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
17
|
+
def initialize(*args)
|
18
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
19
|
+
@type = args.shift
|
20
|
+
@max = args.shift || 0
|
21
|
+
@closed = false
|
22
|
+
@name = opts[:name] || UUID.generate
|
23
|
+
@direction = opts[:direction] || :bidirectional
|
24
|
+
@skip_marshal = opts[:skip_marshal]
|
25
|
+
@close_mutex = Mutex.new
|
26
|
+
@queue = Queues.register(@name, @type, @max)
|
30
27
|
end
|
31
28
|
|
32
29
|
|
@@ -48,7 +45,9 @@ module Agent
|
|
48
45
|
|
49
46
|
def send(object, options={})
|
50
47
|
check_direction(:send)
|
51
|
-
queue
|
48
|
+
q = queue
|
49
|
+
raise Errors::ChannelClosed unless q
|
50
|
+
q.push(object, {:skip_marshal => @skip_marshal}.merge(options))
|
52
51
|
end
|
53
52
|
alias :push :send
|
54
53
|
alias :<< :send
|
@@ -61,7 +60,9 @@ module Agent
|
|
61
60
|
|
62
61
|
def receive(options={})
|
63
62
|
check_direction(:receive)
|
64
|
-
queue
|
63
|
+
q = queue
|
64
|
+
return [nil, false] unless q
|
65
|
+
q.pop(options)
|
65
66
|
end
|
66
67
|
alias :pop :receive
|
67
68
|
|
data/lib/agent/pop.rb
CHANGED
@@ -34,11 +34,9 @@ module Agent
|
|
34
34
|
|
35
35
|
def send
|
36
36
|
@mutex.synchronize do
|
37
|
-
raise Errors::ChannelClosed if @closed
|
38
|
-
|
39
37
|
if @blocking_once
|
40
38
|
_, error = @blocking_once.perform do
|
41
|
-
@object =
|
39
|
+
@object = yield unless @closed
|
42
40
|
@received = true
|
43
41
|
@cvar.signal
|
44
42
|
@notifier.notify(self) if @notifier
|
@@ -47,7 +45,7 @@ module Agent
|
|
47
45
|
return error
|
48
46
|
else
|
49
47
|
begin
|
50
|
-
@object =
|
48
|
+
@object = yield unless @closed
|
51
49
|
@received = true
|
52
50
|
@cvar.signal
|
53
51
|
@notifier.notify(self) if @notifier
|
data/lib/agent/push.rb
CHANGED
@@ -2,10 +2,36 @@ require "agent/errors"
|
|
2
2
|
|
3
3
|
module Agent
|
4
4
|
class Push
|
5
|
+
SKIP_MARSHAL_TYPES = [
|
6
|
+
::Symbol,
|
7
|
+
::Numeric,
|
8
|
+
::NilClass,
|
9
|
+
::TrueClass,
|
10
|
+
::FalseClass,
|
11
|
+
::Queue,
|
12
|
+
::SizedQueue,
|
13
|
+
::Thread,
|
14
|
+
::Mutex,
|
15
|
+
::Monitor,
|
16
|
+
::Module,
|
17
|
+
::IO,
|
18
|
+
::Proc,
|
19
|
+
::Method
|
20
|
+
]
|
21
|
+
|
5
22
|
attr_reader :object, :uuid, :blocking_once, :notifier
|
6
23
|
|
7
24
|
def initialize(object, options={})
|
8
|
-
@object
|
25
|
+
@object = case object
|
26
|
+
when *SKIP_MARSHAL_TYPES
|
27
|
+
object
|
28
|
+
else
|
29
|
+
if options[:skip_marshal]
|
30
|
+
object
|
31
|
+
else
|
32
|
+
Marshal.load(Marshal.dump(object))
|
33
|
+
end
|
34
|
+
end
|
9
35
|
@uuid = options[:uuid] || UUID.generate
|
10
36
|
@blocking_once = options[:blocking_once]
|
11
37
|
@notifier = options[:notifier]
|
data/lib/agent/queue.rb
CHANGED
data/lib/agent/selector.rb
CHANGED
@@ -103,7 +103,7 @@ module Agent
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def execute_case(operation)
|
106
|
-
raise Errors::ChannelClosed if operation.closed?
|
106
|
+
raise Errors::ChannelClosed if operation.closed? && operation.is_a?(Agent::Push)
|
107
107
|
|
108
108
|
cse = @cases[operation.uuid]
|
109
109
|
blk, direction = cse.blk, cse.direction
|
data/lib/agent/version.rb
CHANGED
data/spec/channel_spec.rb
CHANGED
@@ -109,9 +109,9 @@ describe Agent::Channel do
|
|
109
109
|
lambda { @c.send("a") }.should raise_error(Agent::Errors::ChannelClosed)
|
110
110
|
end
|
111
111
|
|
112
|
-
it "should
|
112
|
+
it "should return [nil, false] when receiving from a channel that has already been closed" do
|
113
113
|
@c.close
|
114
|
-
|
114
|
+
@c.receive.should == [nil, false]
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
@@ -213,4 +213,28 @@ describe Agent::Channel do
|
|
213
213
|
end
|
214
214
|
end
|
215
215
|
|
216
|
+
context "marshaling" do
|
217
|
+
it "marshals data by default" do
|
218
|
+
c = channel!(String, 1)
|
219
|
+
string = "foo"
|
220
|
+
c.send(string)
|
221
|
+
string_copy = c.receive[0]
|
222
|
+
string_copy.should == string
|
223
|
+
string_copy.object_id.should_not == string.object_id
|
224
|
+
end
|
225
|
+
|
226
|
+
it "skips marshaling when configured to" do
|
227
|
+
c = channel!(String, 1, :skip_marshal => true)
|
228
|
+
string = "foo"
|
229
|
+
c.send(string)
|
230
|
+
c.receive[0].object_id.should == string.object_id
|
231
|
+
end
|
232
|
+
|
233
|
+
it "skips marshaling for channels by default" do
|
234
|
+
c = channel!(Agent::Channel, 1)
|
235
|
+
c.send(c)
|
236
|
+
c.receive[0].object_id.should == c.object_id
|
237
|
+
end
|
238
|
+
end
|
216
239
|
end
|
240
|
+
|
data/spec/pop_spec.rb
CHANGED
@@ -15,16 +15,16 @@ describe Agent::Pop do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should run multiple times" do
|
18
|
-
@pop.send{
|
18
|
+
@pop.send{1}
|
19
19
|
@pop.should be_received
|
20
|
-
@pop.send{
|
20
|
+
@pop.send{2}
|
21
21
|
@pop.object.should == 2
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should continue when received" do
|
25
25
|
go!{ @pop.wait; @ack.send(Time.now) }
|
26
26
|
sleep 0.2
|
27
|
-
@pop.send{
|
27
|
+
@pop.send{1}
|
28
28
|
|
29
29
|
s, _ = @ack.receive
|
30
30
|
|
@@ -41,11 +41,23 @@ describe Agent::Pop do
|
|
41
41
|
(Time.now - s).should be_within(0.01).of(0)
|
42
42
|
end
|
43
43
|
|
44
|
-
it "be able to be gracefully rolled back" do
|
44
|
+
it "should be able to be gracefully rolled back" do
|
45
45
|
@pop.should_not be_received
|
46
46
|
@pop.send{ raise Agent::Errors::Rollback }
|
47
47
|
@pop.should_not be_received
|
48
48
|
end
|
49
|
+
|
50
|
+
it "should continue when it was already closed" do
|
51
|
+
@pop.close
|
52
|
+
|
53
|
+
go!{ @pop.wait; @ack.send(Time.now) }
|
54
|
+
|
55
|
+
sleep 0.2
|
56
|
+
|
57
|
+
s, _ = @ack.receive
|
58
|
+
|
59
|
+
(Time.now - s).should be_within(0.01).of(0.2)
|
60
|
+
end
|
49
61
|
end
|
50
62
|
|
51
63
|
context "with a blocking_once" do
|
@@ -56,11 +68,12 @@ describe Agent::Pop do
|
|
56
68
|
|
57
69
|
it "should only send only once" do
|
58
70
|
@blocking_once.should_not be_performed
|
59
|
-
@pop.send{
|
71
|
+
@pop.send{1}
|
60
72
|
@pop.should be_received
|
61
73
|
@blocking_once.should be_performed
|
74
|
+
@pop.object.should == 1
|
62
75
|
|
63
|
-
@pop.send{
|
76
|
+
@pop.send{2}
|
64
77
|
@pop.object.should == 1
|
65
78
|
|
66
79
|
lambda{@pop.send{raise "an error"} }.should_not raise_error
|
@@ -73,6 +86,20 @@ describe Agent::Pop do
|
|
73
86
|
@blocking_once.should_not be_performed
|
74
87
|
@pop.should_not be_received
|
75
88
|
end
|
89
|
+
|
90
|
+
it "should send only once even when it is closed" do
|
91
|
+
@pop.close
|
92
|
+
@blocking_once.should_not be_performed
|
93
|
+
@pop.send{1}
|
94
|
+
@pop.should be_received
|
95
|
+
@blocking_once.should be_performed
|
96
|
+
@pop.object.should == nil
|
97
|
+
|
98
|
+
@pop.send{2}
|
99
|
+
@pop.object.should == nil
|
100
|
+
|
101
|
+
lambda{@pop.send{raise "an error"} }.should_not raise_error
|
102
|
+
end
|
76
103
|
end
|
77
104
|
|
78
105
|
context "with a notifier" do
|
@@ -83,7 +110,7 @@ describe Agent::Pop do
|
|
83
110
|
|
84
111
|
it "should notify when being sent" do
|
85
112
|
@notifier.should_not be_notified
|
86
|
-
@pop.send{
|
113
|
+
@pop.send{1}
|
87
114
|
@notifier.should be_notified
|
88
115
|
end
|
89
116
|
|
data/spec/push_spec.rb
CHANGED
@@ -29,7 +29,7 @@ describe Agent::Push do
|
|
29
29
|
|
30
30
|
s, _ = @ack.receive
|
31
31
|
|
32
|
-
(Time.now - s).should be_within(0.
|
32
|
+
(Time.now - s).should be_within(0.02).of(0)
|
33
33
|
end
|
34
34
|
|
35
35
|
it "should raise an error on the waiter when closed" do
|
@@ -44,6 +44,35 @@ describe Agent::Push do
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
+
context "marshaling" do
|
48
|
+
let(:object){ "foo" }
|
49
|
+
let(:skip_marshal){ false }
|
50
|
+
let(:push){ Agent::Push.new(object, :skip_marshal => skip_marshal) }
|
51
|
+
|
52
|
+
it "makes a copy of the object" do
|
53
|
+
push.object.should == object
|
54
|
+
push.object.object_id.should_not == object.object_id
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with an object type that skips marshaling" do
|
58
|
+
let(:object){ ::Queue.new }
|
59
|
+
|
60
|
+
it "does not make a copy of the object" do
|
61
|
+
push.object.should == object
|
62
|
+
push.object.object_id.should == object.object_id
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when skip_marshal is true" do
|
67
|
+
let(:skip_marshal){ true }
|
68
|
+
|
69
|
+
it "does not make a copy of the object" do
|
70
|
+
push.object.should == object
|
71
|
+
push.object.object_id.should == object.object_id
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
47
76
|
context "with a blocking_once" do
|
48
77
|
before do
|
49
78
|
@blocking_once = Agent::BlockingOnce.new
|
data/spec/queue_spec.rb
CHANGED
@@ -158,11 +158,20 @@ describe Agent::Queue do
|
|
158
158
|
@queue.queue.size.should == 0
|
159
159
|
end
|
160
160
|
|
161
|
-
|
162
|
-
@queue.close
|
163
|
-
|
164
|
-
|
165
|
-
|
161
|
+
context "after it is closed" do
|
162
|
+
before{ @queue.close }
|
163
|
+
|
164
|
+
it "should raise an error when #close is called again" do
|
165
|
+
lambda{ @queue.close }.should raise_error(Agent::Errors::ChannelClosed)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should raise an error when a value is pushed onto the queue" do
|
169
|
+
lambda{ @queue.push("1") }.should raise_error(Agent::Errors::ChannelClosed)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should return [nil, false] when popping from the queue" do
|
173
|
+
@queue.pop.should == [nil, false]
|
174
|
+
end
|
166
175
|
end
|
167
176
|
end
|
168
177
|
|
@@ -322,11 +331,20 @@ describe Agent::Queue do
|
|
322
331
|
@queue.pushes.size.should == 0
|
323
332
|
end
|
324
333
|
|
325
|
-
|
326
|
-
@queue.close
|
327
|
-
|
328
|
-
|
329
|
-
|
334
|
+
context "after it is closed" do
|
335
|
+
before{ @queue.close }
|
336
|
+
|
337
|
+
it "should raise an error when #close is called again" do
|
338
|
+
lambda{ @queue.close }.should raise_error(Agent::Errors::ChannelClosed)
|
339
|
+
end
|
340
|
+
|
341
|
+
it "should raise an error when a value is pushed onto the queue" do
|
342
|
+
lambda{ @queue.push("1") }.should raise_error(Agent::Errors::ChannelClosed)
|
343
|
+
end
|
344
|
+
|
345
|
+
it "should return [nil, false] when popping from the queue" do
|
346
|
+
@queue.pop.should == [nil, false]
|
347
|
+
end
|
330
348
|
end
|
331
349
|
end
|
332
350
|
|
data/spec/selector_spec.rb
CHANGED
@@ -108,17 +108,26 @@ describe Agent::Selector do
|
|
108
108
|
r.first.should == :default
|
109
109
|
end
|
110
110
|
|
111
|
-
it "should raise an error if the channel is closed out from under it" do
|
111
|
+
it "should raise an error if the channel is closed out from under it and you are sending to it" do
|
112
112
|
go!{ sleep 0.25; @c.close }
|
113
113
|
|
114
114
|
lambda {
|
115
115
|
select! do |s|
|
116
116
|
s.case(@c, :send, 1)
|
117
|
-
s.case(@c, :receive)
|
118
117
|
end
|
119
118
|
}.should raise_error(Agent::Errors::ChannelClosed)
|
120
119
|
end
|
121
120
|
|
121
|
+
it "should not raise an error if the channel is closed out from under it and you are receiving from it" do
|
122
|
+
go!{ sleep 0.25; @c.close }
|
123
|
+
|
124
|
+
lambda {
|
125
|
+
select! do |s|
|
126
|
+
s.case(@c, :receive){}
|
127
|
+
end
|
128
|
+
}.should_not raise_error
|
129
|
+
end
|
130
|
+
|
122
131
|
context "select immediately available channel" do
|
123
132
|
it "should select read channel" do
|
124
133
|
c = channel!(Integer)
|
@@ -291,7 +300,7 @@ describe Agent::Selector do
|
|
291
300
|
r.first.should == :default
|
292
301
|
end
|
293
302
|
|
294
|
-
it "should raise an error if the channel is closed out from under it" do
|
303
|
+
it "should raise an error if the channel is closed out from under it and you are sending to it" do
|
295
304
|
@c.send(1)
|
296
305
|
|
297
306
|
go!{ sleep 0.25; @c.close }
|
@@ -299,11 +308,20 @@ describe Agent::Selector do
|
|
299
308
|
lambda {
|
300
309
|
select! do |s|
|
301
310
|
s.case(@c, :send, 1)
|
302
|
-
s.case(@c, :send, 2)
|
303
311
|
end
|
304
312
|
}.should raise_error(Agent::Errors::ChannelClosed)
|
305
313
|
end
|
306
314
|
|
315
|
+
it "should not raise an error if the channel is closed out from under it and you are receiving from it" do
|
316
|
+
go!{ sleep 0.25; @c.close }
|
317
|
+
|
318
|
+
lambda {
|
319
|
+
select! do |s|
|
320
|
+
s.case(@c, :receive){}
|
321
|
+
end
|
322
|
+
}.should_not raise_error
|
323
|
+
end
|
324
|
+
|
307
325
|
context "select immediately available channel" do
|
308
326
|
it "should select read channel" do
|
309
327
|
c = channel!(Integer, 1)
|
data/spec/spec_helper.rb
CHANGED
@@ -14,6 +14,7 @@ RSpec.configure do |config|
|
|
14
14
|
config.filter_run :focus
|
15
15
|
|
16
16
|
config.filter_run_excluding :vm => lambda { |version|
|
17
|
-
|
17
|
+
c = defined?(RbConfig) ? RbConfig : Config
|
18
|
+
!(c::CONFIG['ruby_install_name'] =~ /^#{version.to_s}/)
|
18
19
|
}
|
19
20
|
end
|
metadata
CHANGED
@@ -1,46 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.10.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Ilya Grigorik
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2015-02-12 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
description: Agent is a diverse family of related approaches for modelling concurrent
|
@@ -51,8 +46,10 @@ executables: []
|
|
51
46
|
extensions: []
|
52
47
|
extra_rdoc_files: []
|
53
48
|
files:
|
54
|
-
- .gitignore
|
55
|
-
- .rspec
|
49
|
+
- ".gitignore"
|
50
|
+
- ".rspec"
|
51
|
+
- ".ruby-gemset"
|
52
|
+
- ".travis.yml"
|
56
53
|
- Gemfile
|
57
54
|
- Gemfile.lock
|
58
55
|
- README.md
|
@@ -106,27 +103,26 @@ files:
|
|
106
103
|
- spec/wait_group_spec.rb
|
107
104
|
homepage: https://github.com/igrigorik/agent
|
108
105
|
licenses: []
|
106
|
+
metadata: {}
|
109
107
|
post_install_message:
|
110
108
|
rdoc_options: []
|
111
109
|
require_paths:
|
112
110
|
- lib
|
113
111
|
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
-
none: false
|
115
112
|
requirements:
|
116
|
-
- -
|
113
|
+
- - ">="
|
117
114
|
- !ruby/object:Gem::Version
|
118
115
|
version: '0'
|
119
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
-
none: false
|
121
117
|
requirements:
|
122
|
-
- -
|
118
|
+
- - ">="
|
123
119
|
- !ruby/object:Gem::Version
|
124
120
|
version: '0'
|
125
121
|
requirements: []
|
126
122
|
rubyforge_project: agent
|
127
|
-
rubygems_version:
|
123
|
+
rubygems_version: 2.4.5
|
128
124
|
signing_key:
|
129
|
-
specification_version:
|
125
|
+
specification_version: 4
|
130
126
|
summary: Agent is a diverse family of related approaches for modelling concurrent
|
131
127
|
systems, in Ruby
|
132
128
|
test_files:
|
@@ -149,4 +145,3 @@ test_files:
|
|
149
145
|
- spec/spec_helper.rb
|
150
146
|
- spec/uuid_spec.rb
|
151
147
|
- spec/wait_group_spec.rb
|
152
|
-
has_rdoc:
|