mailbox 0.1.0 → 0.1.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/Rakefile +21 -12
- data/VERSION.yml +1 -1
- data/lib/mailbox.rb +66 -50
- data/mailbox.gemspec +5 -2
- data/test/mailbox_test.rb +59 -60
- metadata +13 -4
data/Rakefile
CHANGED
@@ -1,27 +1,36 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
require "rake/testtask"
|
3
|
+
require "rake/rdoctask"
|
3
4
|
require "jeweler"
|
4
5
|
|
5
6
|
task :default => :test
|
6
7
|
|
7
8
|
Rake::TestTask.new do |t|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
t.libs << "test"
|
10
|
+
t.test_files = FileList['test/**/*_test.rb']
|
11
|
+
t.verbose = true
|
11
12
|
end
|
12
13
|
|
13
14
|
Jeweler::Tasks.new do |gemspec|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
gemspec.name = "mailbox"
|
16
|
+
gemspec.summary = "Mailbox is a JRuby module that simplifies concurrency and is backed by JVM threads."
|
17
|
+
gemspec.description = gemspec.summary
|
18
|
+
gemspec.email = "asher.friedman@gmail.com"
|
19
|
+
gemspec.homepage = "http://joelash.github.com/mailbox"
|
20
|
+
gemspec.authors = ["Joel Friedman", "Patrick Farley"]
|
21
|
+
|
22
|
+
gemspec.add_dependency "jretlang"
|
23
|
+
|
24
|
+
gemspec.rubyforge_project = "mailbox"
|
22
25
|
end
|
23
26
|
|
24
27
|
Jeweler::RubyforgeTasks.new do |rubyforge|
|
25
|
-
|
28
|
+
rubyforge.doc_task = "rdoc"
|
29
|
+
end
|
30
|
+
|
31
|
+
Rake::RDocTask.new do |rdoc|
|
32
|
+
rdoc.main = "README"
|
33
|
+
rdoc.rdoc_files.include("README", "lib/**/*.rb")
|
34
|
+
rdoc.rdoc_dir = "rdoc"
|
26
35
|
end
|
27
36
|
|
data/VERSION.yml
CHANGED
data/lib/mailbox.rb
CHANGED
@@ -1,78 +1,94 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'jretlang'
|
3
3
|
|
4
|
+
# Author:: Joel Friedman and Patrick Farley
|
5
|
+
|
6
|
+
# This module is used to simplify the using concurrency
|
7
|
+
# in your application. Using JVM threads as the backing
|
8
|
+
# a function can set to become an asynchronous function
|
9
|
+
# to be used in a actor-model method. Or a function
|
10
|
+
# can be set to be the backing of a named channel
|
11
|
+
# (jretlang channels are used here).
|
4
12
|
module Mailbox
|
5
13
|
|
14
|
+
# Register your jretlang channel as a named channel
|
15
|
+
def register_channel(channel_name, channel)
|
16
|
+
channel_registry = self.class.__channel_registry__
|
17
|
+
channel_registry.each_pair { |key, value| __subscribe__(channel, key) if value == channel_name }
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
6
22
|
def self.included(base)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
def __subscribe__(channel, method)
|
16
|
-
channel.subscribe_on_fiber(__fiber__) { |*args| self.send(method, *args) }
|
17
|
-
end
|
23
|
+
base.extend(Mailbox::ClassMethods)
|
24
|
+
end
|
25
|
+
|
26
|
+
def __subscribe__(channel, method)
|
27
|
+
channel.subscribe_on_fiber(__fiber__) { |*args| self.send(method, *args) }
|
28
|
+
end
|
18
29
|
|
19
30
|
def __started_fiber__
|
20
|
-
|
21
|
-
|
22
|
-
|
31
|
+
fiber = JRL::Fiber.new
|
32
|
+
fiber.start
|
33
|
+
fiber
|
23
34
|
end
|
24
35
|
|
25
36
|
def __fiber__
|
26
|
-
|
37
|
+
@fiber ||= __started_fiber__
|
27
38
|
end
|
28
39
|
|
29
|
-
|
40
|
+
module ClassMethods
|
41
|
+
|
42
|
+
attr_accessor :__channel_registry__
|
30
43
|
|
31
|
-
|
44
|
+
# Notifies Mailbox that the next method added
|
45
|
+
# will be a 'mailslot'. If :channel is provided
|
46
|
+
# then it'll become a subscriber on that channel
|
47
|
+
def mailslot(params={})
|
48
|
+
@next_channel_name = params[:channel]
|
49
|
+
@mailslot = true
|
50
|
+
end
|
32
51
|
|
33
|
-
|
34
|
-
@next_channel_name = params[:channel]
|
35
|
-
@mailslot = true
|
36
|
-
end
|
52
|
+
private
|
37
53
|
|
38
|
-
|
39
|
-
|
54
|
+
def method_added(method_name, &block)
|
55
|
+
return if @adding_mailbox_to_method == method_name
|
40
56
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
57
|
+
unless @mailslot == true
|
58
|
+
private method_name
|
59
|
+
return
|
60
|
+
end
|
45
61
|
|
46
|
-
|
62
|
+
@mailslot = false
|
47
63
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
64
|
+
if @next_channel_name.nil?
|
65
|
+
__setup_on_fiber__(method_name)
|
66
|
+
else
|
67
|
+
__setup_on_channel__(method_name)
|
68
|
+
end
|
53
69
|
|
54
|
-
|
70
|
+
end
|
55
71
|
|
56
|
-
|
57
|
-
|
72
|
+
def __setup_on_fiber__(method_name)
|
73
|
+
alias_method :"__#{method_name}__", method_name
|
58
74
|
|
59
|
-
|
75
|
+
@adding_mailbox_to_method = method_name
|
60
76
|
|
61
|
-
|
62
|
-
|
63
|
-
|
77
|
+
define_method( method_name, lambda do |*args|
|
78
|
+
__fiber__.execute { self.send(:"__#{method_name}__", *args ) }
|
79
|
+
end )
|
64
80
|
|
65
|
-
|
66
|
-
|
81
|
+
@adding_mailbox_to_method = nil
|
82
|
+
end
|
67
83
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
84
|
+
def __setup_on_channel__(method_name)
|
85
|
+
private method_name
|
86
|
+
@__channel_registry__ ||= {}
|
87
|
+
__channel_registry__[method_name] = @next_channel_name
|
88
|
+
@next_channel_name = nil
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
74
92
|
|
75
|
-
end
|
76
|
-
|
77
93
|
end
|
78
94
|
|
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.1.
|
8
|
+
s.version = "0.1.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{2009-10-
|
12
|
+
s.date = %q{2009-10-18}
|
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 = [
|
@@ -38,8 +38,11 @@ Gem::Specification.new do |s|
|
|
38
38
|
s.specification_version = 3
|
39
39
|
|
40
40
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
41
|
+
s.add_runtime_dependency(%q<jretlang>, [">= 0"])
|
41
42
|
else
|
43
|
+
s.add_dependency(%q<jretlang>, [">= 0"])
|
42
44
|
end
|
43
45
|
else
|
46
|
+
s.add_dependency(%q<jretlang>, [">= 0"])
|
44
47
|
end
|
45
48
|
end
|
data/test/mailbox_test.rb
CHANGED
@@ -4,71 +4,70 @@ require 'test/unit'
|
|
4
4
|
require File.dirname(__FILE__) + "/../lib/mailbox"
|
5
5
|
|
6
6
|
module Latches
|
7
|
-
|
7
|
+
include_package 'java.util.concurrent'
|
8
8
|
end
|
9
9
|
|
10
10
|
class MailboxTest < Test::Unit::TestCase
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
klass.new(a_channel)
|
12
|
+
def test_mailslot_causes_execution_on_separate_thread
|
13
|
+
|
14
|
+
klass = Class.new do
|
15
|
+
include Mailbox
|
16
|
+
|
17
|
+
mailslot
|
18
|
+
def test_method(latch, thread_ids)
|
19
|
+
thread_ids << Thread.current.object_id
|
20
|
+
latch.count_down
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
thread_ids = []
|
25
|
+
latch = Latches::CountDownLatch.new( 1 )
|
26
|
+
klass.new.test_method(latch, thread_ids)
|
27
|
+
|
28
|
+
assert( latch.await( 1, Latches::TimeUnit::SECONDS ), "Timed out" )
|
29
|
+
assert_not_equal Thread.current.object_id, thread_ids.first
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_non_mailslot_methods_become_private
|
34
|
+
|
35
|
+
klass = Class.new do
|
36
|
+
include Mailbox
|
37
|
+
|
38
|
+
def bar
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
exception = assert_raise NoMethodError do
|
43
|
+
klass.new.bar
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_match /private method `bar'/, exception.message
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_should_supports_channels
|
50
|
+
|
51
|
+
klass = Class.new do
|
52
|
+
include Mailbox
|
53
|
+
|
54
|
+
def initialize(channel)
|
55
|
+
register_channel :test_channel, channel
|
56
|
+
end
|
57
|
+
|
58
|
+
mailslot :channel => :test_channel
|
59
|
+
def test_method(latch)
|
60
|
+
latch.count_down
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
latch = Latches::CountDownLatch.new 1
|
65
|
+
a_channel = JRL::Channel.new
|
66
|
+
|
67
|
+
klass.new(a_channel)
|
69
68
|
a_channel.publish latch
|
70
|
-
|
71
|
-
|
69
|
+
|
70
|
+
assert latch.await( 1, Latches::TimeUnit::SECONDS ), "Timed out"
|
72
71
|
|
73
72
|
end
|
74
73
|
|
metadata
CHANGED
@@ -49,15 +49,24 @@ requirements: []
|
|
49
49
|
authors:
|
50
50
|
- Joel Friedman
|
51
51
|
- Patrick Farley
|
52
|
-
date: 2009-10-
|
52
|
+
date: 2009-10-18 05:00:00 +00:00
|
53
53
|
platform: ruby
|
54
54
|
test_files:
|
55
55
|
- test/mailbox_test.rb
|
56
56
|
version: !ruby/object:Gem::Version
|
57
|
-
version: 0.1.
|
57
|
+
version: 0.1.1
|
58
58
|
require_paths:
|
59
59
|
- lib
|
60
|
-
dependencies:
|
61
|
-
|
60
|
+
dependencies:
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
type: :runtime
|
69
|
+
version_requirement:
|
70
|
+
name: jretlang
|
62
71
|
bindir: bin
|
63
72
|
has_rdoc: true
|