async_methods 1.0.2 → 1.0.3
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/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
|