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 CHANGED
@@ -4,4 +4,5 @@ rdoc/*
4
4
  mailbox.iws
5
5
  .rakeTasks
6
6
  TAGS
7
+ tags
7
8
  run_tags.rb
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :major: 0
3
3
  :minor: 2
4
- :patch: 0
4
+ :patch: 1
5
5
  :build:
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__) { |*args| self.send(method, *args) }
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
- result = self.send(:"__#{method_name}__", *args )
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
- latch.await if replyable
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.0"
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-03-09}
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.3.1" jdkType="JRUBY_SDK" />
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 relativePaths="false" version="4">
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
- assert_equal "response", klass.new.test_method
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
- - 0
9
- version: 0.2.0
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-03-09 00:00:00 -06:00
18
+ date: 2010-04-21 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency