thespian 0.0.1 → 0.1.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.
- data/.travis.yml +7 -0
- data/CHANGELOG +8 -0
- data/README.rdoc +49 -3
- data/Rakefile +8 -0
- data/examples/linked.rb +36 -30
- data/examples/producer_consumer.rb +25 -17
- data/examples/task_processor.rb +9 -5
- data/lib/thespian.rb +10 -2
- data/lib/thespian/actor.rb +24 -35
- data/lib/thespian/dsl.rb +5 -0
- data/lib/thespian/example.rb +41 -0
- data/lib/thespian/strategies/fiber.rb +52 -0
- data/lib/thespian/strategies/interface.rb +35 -0
- data/lib/thespian/strategies/process.rb +73 -0
- data/lib/thespian/strategies/thread.rb +74 -0
- data/lib/thespian/version.rb +1 -1
- data/spec/actor_spec.rb +51 -29
- data/spec/classes_spec.rb +22 -0
- data/spec/spec_helper.rb +21 -19
- data/spec/strategies/fiber_spec.rb +42 -0
- data/spec/strategies/interface.rb +91 -0
- data/spec/strategies/thread_spec.rb +17 -0
- data/spec/thespian_spec.rb +65 -0
- data/thespian.gemspec +6 -2
- metadata +76 -10
@@ -0,0 +1,42 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Thespian
|
4
|
+
module Strategy
|
5
|
+
|
6
|
+
if supports_fibers?
|
7
|
+
|
8
|
+
require "eventmachine"
|
9
|
+
require "strand"
|
10
|
+
|
11
|
+
describe Fiber do
|
12
|
+
|
13
|
+
let(:strategy){ Fiber.new{ nil } }
|
14
|
+
|
15
|
+
around(:each) do |example|
|
16
|
+
EM.run do
|
17
|
+
Strand.new do
|
18
|
+
example.run
|
19
|
+
EM.stop
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it_should_behave_like Interface do
|
25
|
+
def sleep(n)
|
26
|
+
Strand.sleep(n)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
else
|
33
|
+
|
34
|
+
describe "Fiber" do
|
35
|
+
it "requires ruby 1.9 or higher" do
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Thespian
|
4
|
+
module Strategy
|
5
|
+
|
6
|
+
shared_examples_for Interface do
|
7
|
+
|
8
|
+
context "#start" do
|
9
|
+
|
10
|
+
before(:all){ File.unlink("test.txt") rescue nil }
|
11
|
+
after(:all){ File.unlink("test.txt") rescue nil }
|
12
|
+
|
13
|
+
it "eventually calls the block" do
|
14
|
+
described_class.new{ File.open("test.txt", "w") }.start
|
15
|
+
count = 0
|
16
|
+
while not File.exists?("test.txt") and count < 5
|
17
|
+
sleep(0.01)
|
18
|
+
count += 1
|
19
|
+
end
|
20
|
+
File.should exist("test.txt")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
context "#<<" do
|
26
|
+
|
27
|
+
it "should put a message in the mailbox" do
|
28
|
+
strategy << :message
|
29
|
+
strategy.mailbox_size.should == 1
|
30
|
+
strategy.receive.should == :message
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
context "#receive" do
|
36
|
+
|
37
|
+
it "should return a message from the mailbox" do
|
38
|
+
strategy << 1 << 2 << 3
|
39
|
+
strategy.mailbox_size.should == 3
|
40
|
+
strategy.receive.should == 1
|
41
|
+
strategy.receive.should == 2
|
42
|
+
strategy.receive.should == 3
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
context "#mailbox_size" do
|
48
|
+
|
49
|
+
it "returns how many messages are in the mailbox" do
|
50
|
+
strategy << 1
|
51
|
+
strategy.mailbox_size.should == 1
|
52
|
+
strategy << 1
|
53
|
+
strategy.mailbox_size.should == 2
|
54
|
+
strategy.receive
|
55
|
+
strategy.mailbox_size.should == 1
|
56
|
+
strategy.receive
|
57
|
+
strategy.mailbox_size.should == 0
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
context "#messages" do
|
63
|
+
|
64
|
+
it "returns an array of messages" do
|
65
|
+
strategy << 1
|
66
|
+
strategy.messages.should == [1]
|
67
|
+
strategy << 2
|
68
|
+
strategy.messages.should == [1, 2]
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
context "#stop" do
|
74
|
+
|
75
|
+
before(:each){ strategy.start }
|
76
|
+
|
77
|
+
it "puts a stop message in the mailbox" do
|
78
|
+
strategy.stop
|
79
|
+
strategy.messages.any?{ |m| m.kind_of?(Stop)}.should be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
it "blocks until the async primitive is done" do
|
83
|
+
strategy.stop
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Thespian
|
2
|
+
|
3
|
+
describe Thespian do
|
4
|
+
context "when included in a class" do
|
5
|
+
|
6
|
+
let(:klass){ Class.new{ include Thespian } }
|
7
|
+
|
8
|
+
it "defines #actor on the class" do
|
9
|
+
klass.should respond_to(:actor)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "defines #actor on instances of the class" do
|
13
|
+
klass.new.should respond_to(:actor)
|
14
|
+
end
|
15
|
+
|
16
|
+
context "#actor on the class" do
|
17
|
+
|
18
|
+
before(:each) do
|
19
|
+
klass.actor.instance_variable_set(:@receive_block, nil)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "defines how messages should be processed" do
|
23
|
+
klass.actor.receive_block.should be_nil
|
24
|
+
klass.actor{ |message| nil }
|
25
|
+
klass.actor.receive_block.should be_a(Proc)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "has method #receive which also defines how messages should be processed" do
|
29
|
+
klass.actor.receive_block.should be_nil
|
30
|
+
klass.actor.receive{ |message| nil }
|
31
|
+
klass.actor.receive_block.should be_a(Proc)
|
32
|
+
end
|
33
|
+
|
34
|
+
if supports_fibers?
|
35
|
+
it "allows you to set mode when defining the message handling block" do
|
36
|
+
klass.new.actor.options[:mode].should == :thread
|
37
|
+
klass.actor(:mode => :fiber){ |message| nil }
|
38
|
+
klass.new.actor.options[:mode].should == :fiber
|
39
|
+
klass.actor(:mode => :thread){ |message| nil }
|
40
|
+
klass.new.actor.options[:mode].should == :thread
|
41
|
+
end
|
42
|
+
|
43
|
+
it "allows you to set mode" do
|
44
|
+
klass.new.actor.options[:mode].should == :thread
|
45
|
+
klass.actor.options[:mode] = :fiber
|
46
|
+
klass.actor{ |message| nil }
|
47
|
+
klass.new.actor.options[:mode].should == :fiber
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
context "#actor on instances of the class" do
|
54
|
+
|
55
|
+
it "returns an instance of Actor" do
|
56
|
+
object = klass.new
|
57
|
+
object.actor.should be_an(Actor)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
data/thespian.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.authors = ["Christopher J. Bottaro"]
|
9
9
|
s.email = ["cjbottaro@alumni.cs.utexas.edu"]
|
10
10
|
s.homepage = "https://github.com/cjbottaro/thespian"
|
11
|
-
s.summary = %q{Implementation of actor pattern
|
12
|
-
s.description = %q{Ruby implementation of actor pattern
|
11
|
+
s.summary = %q{Implementation of actor pattern for use with threads and/or fibers}
|
12
|
+
s.description = %q{Ruby implementation of actor pattern for use with threads and/or fibers}
|
13
13
|
|
14
14
|
s.rubyforge_project = "thespian"
|
15
15
|
|
@@ -22,5 +22,9 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_development_dependency "rspec"
|
23
23
|
s.add_development_dependency "rr"
|
24
24
|
s.add_development_dependency "rdoc"
|
25
|
+
s.add_development_dependency "rake"
|
26
|
+
s.add_development_dependency "pry"
|
27
|
+
s.add_development_dependency "strand"
|
28
|
+
s.add_development_dependency "eventmachine"
|
25
29
|
# s.add_runtime_dependency "rest-client"
|
26
30
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thespian
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
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: 2012-
|
12
|
+
date: 2012-02-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70274003933020 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70274003933020
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rr
|
27
|
-
requirement: &
|
27
|
+
requirement: &70274003932460 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70274003932460
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rdoc
|
38
|
-
requirement: &
|
38
|
+
requirement: &70274003931800 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,8 +43,52 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
47
|
-
|
46
|
+
version_requirements: *70274003931800
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: &70274003931140 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70274003931140
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: pry
|
60
|
+
requirement: &70274003930600 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70274003930600
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: strand
|
71
|
+
requirement: &70274003930080 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70274003930080
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: eventmachine
|
82
|
+
requirement: &70274003929580 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70274003929580
|
91
|
+
description: Ruby implementation of actor pattern for use with threads and/or fibers
|
48
92
|
email:
|
49
93
|
- cjbottaro@alumni.cs.utexas.edu
|
50
94
|
executables: []
|
@@ -52,6 +96,7 @@ extensions: []
|
|
52
96
|
extra_rdoc_files: []
|
53
97
|
files:
|
54
98
|
- .gitignore
|
99
|
+
- .travis.yml
|
55
100
|
- CHANGELOG
|
56
101
|
- Gemfile
|
57
102
|
- README.rdoc
|
@@ -63,9 +108,19 @@ files:
|
|
63
108
|
- lib/thespian/actor.rb
|
64
109
|
- lib/thespian/dsl.rb
|
65
110
|
- lib/thespian/errors.rb
|
111
|
+
- lib/thespian/example.rb
|
112
|
+
- lib/thespian/strategies/fiber.rb
|
113
|
+
- lib/thespian/strategies/interface.rb
|
114
|
+
- lib/thespian/strategies/process.rb
|
115
|
+
- lib/thespian/strategies/thread.rb
|
66
116
|
- lib/thespian/version.rb
|
67
117
|
- spec/actor_spec.rb
|
118
|
+
- spec/classes_spec.rb
|
68
119
|
- spec/spec_helper.rb
|
120
|
+
- spec/strategies/fiber_spec.rb
|
121
|
+
- spec/strategies/interface.rb
|
122
|
+
- spec/strategies/thread_spec.rb
|
123
|
+
- spec/thespian_spec.rb
|
69
124
|
- thespian.gemspec
|
70
125
|
homepage: https://github.com/cjbottaro/thespian
|
71
126
|
licenses: []
|
@@ -79,18 +134,29 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
79
134
|
- - ! '>='
|
80
135
|
- !ruby/object:Gem::Version
|
81
136
|
version: '0'
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
hash: 3755044122751506254
|
82
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
141
|
none: false
|
84
142
|
requirements:
|
85
143
|
- - ! '>='
|
86
144
|
- !ruby/object:Gem::Version
|
87
145
|
version: '0'
|
146
|
+
segments:
|
147
|
+
- 0
|
148
|
+
hash: 3755044122751506254
|
88
149
|
requirements: []
|
89
150
|
rubyforge_project: thespian
|
90
151
|
rubygems_version: 1.8.11
|
91
152
|
signing_key:
|
92
153
|
specification_version: 3
|
93
|
-
summary: Implementation of actor pattern
|
154
|
+
summary: Implementation of actor pattern for use with threads and/or fibers
|
94
155
|
test_files:
|
95
156
|
- spec/actor_spec.rb
|
157
|
+
- spec/classes_spec.rb
|
96
158
|
- spec/spec_helper.rb
|
159
|
+
- spec/strategies/fiber_spec.rb
|
160
|
+
- spec/strategies/interface.rb
|
161
|
+
- spec/strategies/thread_spec.rb
|
162
|
+
- spec/thespian_spec.rb
|