mailbox 0.2.0 → 0.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/.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