async_methods 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/async_methods.gemspec +2 -2
- data/lib/async_methods/async_methods.rb +21 -10
- data/spec/async_method_spec.rb +21 -0
- metadata +4 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.3
|
data/async_methods.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{async_methods}
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.0.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Durand"]
|
12
|
-
s.date = %q{2011-01-
|
12
|
+
s.date = %q{2011-01-24}
|
13
13
|
s.description = %q{Gem that adds asynchronous method calls for all methods on every object to aid in throughput on I/O bound processes. This is intended to improve throughput on I/O bound processes like making several HTTP calls in row.}
|
14
14
|
s.email = %q{brian@embellishedvisions.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -14,7 +14,12 @@ module AsyncMethods
|
|
14
14
|
method = method.to_s
|
15
15
|
if method[0, 6] == 'async_'
|
16
16
|
method = method.to_s
|
17
|
-
|
17
|
+
called_method = method[6 , method.length]
|
18
|
+
if Thread.critical
|
19
|
+
return send(called_method, *args, &block)
|
20
|
+
else
|
21
|
+
return Proxy.new(self, called_method, args, &block)
|
22
|
+
end
|
18
23
|
else
|
19
24
|
# Keep track of the current missing method calls to keep out of an infinite loop
|
20
25
|
stack = Thread.current[:async_method_missing_methods] ||= []
|
@@ -23,6 +28,10 @@ module AsyncMethods
|
|
23
28
|
begin
|
24
29
|
stack.push(sig)
|
25
30
|
return method_missing_without_async(method, *args, &block)
|
31
|
+
rescue Exception => e
|
32
|
+
# Strip this method from the stack trace as it adds confusion
|
33
|
+
e.backtrace.reject!{|line| line.include?(__FILE__)}
|
34
|
+
raise e
|
26
35
|
ensure
|
27
36
|
stack.pop
|
28
37
|
end
|
@@ -46,7 +55,7 @@ module AsyncMethods
|
|
46
55
|
end
|
47
56
|
|
48
57
|
def eql? (sig)
|
49
|
-
sig.kind_of(MethodSignature)
|
58
|
+
sig.kind_of(MethodSignature) && sig.object == @object && sig.method == @method
|
50
59
|
end
|
51
60
|
|
52
61
|
end
|
@@ -54,22 +63,24 @@ module AsyncMethods
|
|
54
63
|
# The proxy object does all the heavy lifting.
|
55
64
|
class Proxy
|
56
65
|
# These methods we don't want to override. All other existing methods will be redefined.
|
57
|
-
PROTECTED_METHODS = %w(initialize __proxy_result__ __proxy_loaded__
|
66
|
+
PROTECTED_METHODS = %w(initialize method_missing __proxy_result__ __proxy_loaded__ __send__ __id__ object_id)
|
67
|
+
|
68
|
+
# Override already defined methods on Object to proxy them to the result object
|
69
|
+
instance_methods.each do |m|
|
70
|
+
undef_method(m) unless PROTECTED_METHODS.include?(m.to_s)
|
71
|
+
end
|
58
72
|
|
59
73
|
def initialize (obj, method, args = [], &block)
|
60
|
-
|
61
|
-
|
62
|
-
eval "def self.#{m} (*args, &block); __proxy_result__.send(:#{m}, *args, &block); end" unless PROTECTED_METHODS.include?(m.to_s)
|
63
|
-
end
|
64
|
-
|
74
|
+
@proxy_result = nil
|
75
|
+
@proxy_exception = nil
|
65
76
|
@thread = Thread.new do
|
66
77
|
begin
|
67
|
-
if obj
|
78
|
+
if obj && method
|
68
79
|
@proxy_result = obj.send(method, *args, &block)
|
69
80
|
else
|
70
81
|
@proxy_result = block.call
|
71
82
|
end
|
72
|
-
rescue
|
83
|
+
rescue Exception => e
|
73
84
|
@proxy_exception = e
|
74
85
|
end
|
75
86
|
end
|
data/spec/async_method_spec.rb
CHANGED
@@ -24,6 +24,16 @@ describe AsyncMethods::InstanceMethods do
|
|
24
24
|
proxy.__proxy_loaded__.should == true
|
25
25
|
end
|
26
26
|
|
27
|
+
it "should remove itself from stacktraces thrown in method_missing" do
|
28
|
+
begin
|
29
|
+
"object".call_a_missing_method_that_does_not_exist
|
30
|
+
raise "should not get here"
|
31
|
+
rescue => e
|
32
|
+
async_source_file = File.expand_path("../../lib/async_methods/async_methods.rb", __FILE__)
|
33
|
+
File.exist?(async_source_file).should == true
|
34
|
+
e.backtrace.join("\n").should_not include(async_source_file)
|
35
|
+
end
|
36
|
+
end
|
27
37
|
end
|
28
38
|
|
29
39
|
describe AsyncMethods::Proxy do
|
@@ -99,4 +109,15 @@ describe AsyncMethods::Proxy do
|
|
99
109
|
object.async_real_method_called.should == true
|
100
110
|
end
|
101
111
|
|
112
|
+
it "should not open a new thread if Thread.critical is true" do
|
113
|
+
begin
|
114
|
+
Thread.critical = true
|
115
|
+
Thread.should_not_receive(:new)
|
116
|
+
proxy = "xxx".async_to_s
|
117
|
+
proxy.should == "xxx"
|
118
|
+
ensure
|
119
|
+
Thread.critical = false
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
102
123
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async_methods
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 3
|
10
|
+
version: 1.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brian Durand
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-24 00:00:00 -06:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|