mailbox 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/VERSION.yml +1 -1
- data/lib/mailbox.rb +29 -9
- data/mailbox.gemspec +2 -2
- data/mailbox.iml +1 -4
- data/mailbox.ipr +2 -48
- data/test/mailbox_test.rb +72 -2
- metadata +3 -3
data/.gitignore
CHANGED
data/VERSION.yml
CHANGED
data/lib/mailbox.rb
CHANGED
@@ -23,6 +23,10 @@ module Mailbox
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
def verbose_output_to method_name
|
27
|
+
@verbose_target = method_name
|
28
|
+
end
|
29
|
+
|
26
30
|
class << self
|
27
31
|
# Used to tell +Mailbox+ that all +mailslot+
|
28
32
|
# methods should be run on the calling thread.
|
@@ -37,7 +41,9 @@ module Mailbox
|
|
37
41
|
end
|
38
42
|
|
39
43
|
def __subscribe__(channel, method)
|
40
|
-
channel.subscribe_on_fiber(__fiber__)
|
44
|
+
channel.subscribe_on_fiber(__fiber__) do |*args|
|
45
|
+
self.send(method, *args)
|
46
|
+
end
|
41
47
|
end
|
42
48
|
|
43
49
|
def __subscribe_with_single_reply__(channel, method)
|
@@ -82,6 +88,7 @@ module Mailbox
|
|
82
88
|
def mailslot(params={})
|
83
89
|
@next_channel_name = params[:channel]
|
84
90
|
@replyable = params[:replyable]
|
91
|
+
@timeout = params[:timeout].nil? ? -1 : params[:timeout] * 1000
|
85
92
|
@exception = params[:exception]
|
86
93
|
@mailslot = true
|
87
94
|
end
|
@@ -93,7 +100,7 @@ module Mailbox
|
|
93
100
|
@mailslot = false
|
94
101
|
|
95
102
|
if @next_channel_name.nil?
|
96
|
-
__setup_on_fiber__(method_name, @replyable)
|
103
|
+
__setup_on_fiber__(method_name, @replyable, @timeout)
|
97
104
|
else
|
98
105
|
__setup_on_channel__(method_name, @replyable)
|
99
106
|
end
|
@@ -102,7 +109,7 @@ module Mailbox
|
|
102
109
|
|
103
110
|
end
|
104
111
|
|
105
|
-
def __setup_on_fiber__(method_name, replyable)
|
112
|
+
def __setup_on_fiber__(method_name, replyable, timeout)
|
106
113
|
return super if __is_adding_mailbox_to_method__
|
107
114
|
|
108
115
|
alias_method :"__#{method_name}__", method_name
|
@@ -110,13 +117,16 @@ module Mailbox
|
|
110
117
|
|
111
118
|
exception_method, @exception = @exception, nil
|
112
119
|
define_method method_name do |*args|
|
113
|
-
|
120
|
+
|
121
|
+
self.send(@verbose_target, "enqueued #{method_name}") if defined? @verbose_target
|
122
|
+
|
114
123
|
result = nil
|
115
124
|
latch = JRL::Concurrent::CountDownLatch.new(1) if replyable
|
116
|
-
|
117
|
-
__fiber__.execute do
|
125
|
+
|
126
|
+
__fiber__.execute do
|
118
127
|
begin
|
119
|
-
|
128
|
+
self.send(@verbose_target, "dequeued #{method_name}") if defined? @verbose_target
|
129
|
+
result = self.send(:"__#{method_name}__", *args )
|
120
130
|
rescue Exception => ex
|
121
131
|
raise if exception_method.nil?
|
122
132
|
self.send(:"#{exception_method}", ex)
|
@@ -124,8 +134,18 @@ module Mailbox
|
|
124
134
|
latch.count_down if replyable
|
125
135
|
end
|
126
136
|
end
|
127
|
-
|
128
|
-
|
137
|
+
|
138
|
+
is_timeout = false
|
139
|
+
if replyable
|
140
|
+
if timeout == -1
|
141
|
+
latch.await
|
142
|
+
else
|
143
|
+
is_timeout = !(latch.await timeout, JRL::Concurrent::TimeUnit::MILLISECONDS)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
raise Exception.new("#{method_name} message timeout after #{timeout/1000} seconds") if is_timeout
|
148
|
+
|
129
149
|
return result
|
130
150
|
|
131
151
|
end
|
data/mailbox.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mailbox}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Joel Friedman", "Patrick Farley"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-04-21}
|
13
13
|
s.description = %q{Mailbox is a JRuby module that simplifies concurrency and is backed by JVM threads.}
|
14
14
|
s.email = %q{asher.friedman@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/mailbox.iml
CHANGED
@@ -3,11 +3,8 @@
|
|
3
3
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
4
4
|
<exclude-output />
|
5
5
|
<content url="file://$MODULE_DIR$" />
|
6
|
-
<orderEntry type="jdk" jdkName="JRuby SDK 1.
|
6
|
+
<orderEntry type="jdk" jdkName="JRuby SDK 1.4.0" jdkType="JRUBY_SDK" />
|
7
7
|
<orderEntry type="sourceFolder" forTests="false" />
|
8
8
|
</component>
|
9
|
-
<component name="RModuleSettingsStorage">
|
10
|
-
<RMODULE_SETTINGS_STORAGE_ID NAME="NUMBER" VALUE="0" />
|
11
|
-
</component>
|
12
9
|
</module>
|
13
10
|
|
data/mailbox.ipr
CHANGED
@@ -1,18 +1,13 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<project
|
2
|
+
<project version="4">
|
3
3
|
<component name="AntConfiguration">
|
4
4
|
<defaultAnt bundledAnt="true" />
|
5
5
|
</component>
|
6
6
|
<component name="BuildJarProjectSettings">
|
7
7
|
<option name="BUILD_JARS_ON_MAKE" value="false" />
|
8
8
|
</component>
|
9
|
-
<component name="CodeStyleSettingsManager">
|
10
|
-
<option name="PER_PROJECT_SETTINGS" />
|
11
|
-
<option name="USE_PER_PROJECT_SETTINGS" value="false" />
|
12
|
-
</component>
|
13
9
|
<component name="CompilerConfiguration">
|
14
10
|
<option name="DEFAULT_COMPILER" value="Javac" />
|
15
|
-
<option name="DEPLOY_AFTER_MAKE" value="0" />
|
16
11
|
<resourceExtensions>
|
17
12
|
<entry name=".+\.(properties|xml|html|dtd|tld)" />
|
18
13
|
<entry name=".+\.(gif|png|jpeg|jpg)" />
|
@@ -29,6 +24,7 @@
|
|
29
24
|
<entry name="?*.tld" />
|
30
25
|
<entry name="?*.ftl" />
|
31
26
|
</wildcardResourcePatterns>
|
27
|
+
<annotationProcessing enabled="false" useClasspath="true" />
|
32
28
|
</component>
|
33
29
|
<component name="CopyrightManager" default="">
|
34
30
|
<module2copyright />
|
@@ -37,33 +33,11 @@
|
|
37
33
|
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
38
34
|
</component>
|
39
35
|
<component name="EclipseCompilerSettings">
|
40
|
-
<option name="DEBUGGING_INFO" value="true" />
|
41
36
|
<option name="GENERATE_NO_WARNINGS" value="true" />
|
42
37
|
<option name="DEPRECATION" value="false" />
|
43
|
-
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
|
44
|
-
<option name="MAXIMUM_HEAP_SIZE" value="128" />
|
45
38
|
</component>
|
46
39
|
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
47
40
|
<component name="IdProvider" IDEtalkID="2A4BC5ABDEB6DBFA33020D902AA1570C" />
|
48
|
-
<component name="InspectionProjectProfileManager">
|
49
|
-
<option name="PROJECT_PROFILE" value="Project Default" />
|
50
|
-
<option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
|
51
|
-
<scopes />
|
52
|
-
<profiles>
|
53
|
-
<profile version="1.0" is_locked="false">
|
54
|
-
<option name="myName" value="Project Default" />
|
55
|
-
<option name="myLocal" value="false" />
|
56
|
-
</profile>
|
57
|
-
</profiles>
|
58
|
-
<list size="0" />
|
59
|
-
</component>
|
60
|
-
<component name="JavacSettings">
|
61
|
-
<option name="DEBUGGING_INFO" value="true" />
|
62
|
-
<option name="GENERATE_NO_WARNINGS" value="false" />
|
63
|
-
<option name="DEPRECATION" value="true" />
|
64
|
-
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
|
65
|
-
<option name="MAXIMUM_HEAP_SIZE" value="128" />
|
66
|
-
</component>
|
67
41
|
<component name="JavadocGenerationManager">
|
68
42
|
<option name="OUTPUT_DIRECTORY" />
|
69
43
|
<option name="OPTION_SCOPE" value="protected" />
|
@@ -81,14 +55,6 @@
|
|
81
55
|
<option name="LOCALE" />
|
82
56
|
<option name="OPEN_IN_BROWSER" value="true" />
|
83
57
|
</component>
|
84
|
-
<component name="JikesSettings">
|
85
|
-
<option name="JIKES_PATH" value="" />
|
86
|
-
<option name="DEBUGGING_INFO" value="true" />
|
87
|
-
<option name="DEPRECATION" value="true" />
|
88
|
-
<option name="GENERATE_NO_WARNINGS" value="false" />
|
89
|
-
<option name="IS_EMACS_ERRORS_MODE" value="true" />
|
90
|
-
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
|
91
|
-
</component>
|
92
58
|
<component name="Palette2">
|
93
59
|
<group name="Swing">
|
94
60
|
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
@@ -213,11 +179,6 @@
|
|
213
179
|
<component name="ProjectDetails">
|
214
180
|
<option name="projectName" value="mailbox" />
|
215
181
|
</component>
|
216
|
-
<component name="ProjectFileVersion" converted="true">
|
217
|
-
<converter id="javaee-modules" />
|
218
|
-
<converter id="ror-modules" />
|
219
|
-
<converter id="SelenaRunConfToDiana" />
|
220
|
-
</component>
|
221
182
|
<component name="ProjectKey">
|
222
183
|
<option name="state" value="project:///Users/garethjones/sandbox/mailbox/mailbox.ipr" />
|
223
184
|
</component>
|
@@ -236,13 +197,6 @@
|
|
236
197
|
</value>
|
237
198
|
</option>
|
238
199
|
</component>
|
239
|
-
<component name="RmicSettings">
|
240
|
-
<option name="IS_EANABLED" value="false" />
|
241
|
-
<option name="DEBUGGING_INFO" value="true" />
|
242
|
-
<option name="GENERATE_NO_WARNINGS" value="false" />
|
243
|
-
<option name="GENERATE_IIOP_STUBS" value="false" />
|
244
|
-
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
|
245
|
-
</component>
|
246
200
|
<component name="SvnBranchConfigurationManager">
|
247
201
|
<option name="mySupportsUserInfoFilter" value="true" />
|
248
202
|
</component>
|
data/test/mailbox_test.rb
CHANGED
@@ -142,12 +142,82 @@ class MailboxTest < Test::Unit::TestCase
|
|
142
142
|
|
143
143
|
mailslot :replyable => true
|
144
144
|
def test_method
|
145
|
-
"response"
|
145
|
+
["response", JThread.current_thread.name]
|
146
146
|
end
|
147
147
|
end
|
148
148
|
|
149
|
-
|
149
|
+
response, name = klass.new.test_method
|
150
|
+
assert_equal "response", response
|
151
|
+
assert_not_equal JThread.current_thread.name, name
|
150
152
|
|
151
153
|
end
|
152
154
|
|
155
|
+
def test_replyable_messages_should_respect_timeout
|
156
|
+
|
157
|
+
klass = Class.new do
|
158
|
+
include Mailbox
|
159
|
+
|
160
|
+
mailslot :replyable => true, :timeout => 0.1
|
161
|
+
def test_method
|
162
|
+
sleep 1
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
e = assert_raise(Exception) { klass.new.test_method }
|
167
|
+
assert_equal e.message, "test_method message timeout after 0.1 seconds"
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_replyable_messages_should_respect_non_timeout
|
172
|
+
|
173
|
+
klass = Class.new do
|
174
|
+
include Mailbox
|
175
|
+
|
176
|
+
mailslot :replyable => true, :timeout => 1
|
177
|
+
def test_method
|
178
|
+
return 'ok'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
assert_equal 'ok', klass.new.test_method
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_should_expose_hooks_to_message_enqueue_and_dequeue
|
187
|
+
|
188
|
+
|
189
|
+
klass = Class.new do
|
190
|
+
include Mailbox
|
191
|
+
attr_accessor :msg_info
|
192
|
+
|
193
|
+
def initialize(latch)
|
194
|
+
verbose_output_to :msg_monitor
|
195
|
+
|
196
|
+
@latch = latch
|
197
|
+
@msg_info = []
|
198
|
+
end
|
199
|
+
|
200
|
+
mailslot :replyable => true
|
201
|
+
def test_method
|
202
|
+
@latch.count_down
|
203
|
+
end
|
204
|
+
|
205
|
+
def msg_monitor(info)
|
206
|
+
@msg_info << info
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
latch = JRL::Concurrent::Latch.new 2
|
212
|
+
|
213
|
+
test_agent = klass.new latch
|
214
|
+
test_agent.test_method
|
215
|
+
test_agent.test_method
|
216
|
+
|
217
|
+
assert latch.await(1), "timed out waiting for test_method to trip latch twice"
|
218
|
+
|
219
|
+
expected = ['enqueued test_method', 'dequeued test_method', 'enqueued test_method', 'dequeued test_method']
|
220
|
+
assert_equal expected, test_agent.msg_info
|
221
|
+
end
|
222
|
+
|
153
223
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 1
|
9
|
+
version: 0.2.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Joel Friedman
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-04-21 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|