-
Notifications
You must be signed in to change notification settings - Fork 36
/
retryable_stub_adapter.rb
80 lines (71 loc) · 2.44 KB
/
retryable_stub_adapter.rb
1
2
3
4
5
6
7
8
9
10
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
69
70
71
72
73
74
75
76
77
78
79
80
module VSphereCloud
module SdkHelpers
class RetryableStubAdapter
PC = VimSdk::Vmodl::Query::PropertyCollector
def initialize(stub_adapter, logger, retry_judge=nil, retryer=nil)
@stub_adapter = stub_adapter
@logger = logger
@retry_judge = retry_judge || RetryJudge.new
@retryer = retryer || Retryer.new
end
def invoke_method(managed_object, method_info, arguments)
method_name = method_info.wsdl_name
method_result = @retryer.try do |i|
result = nil
err = nil
if i == 0
@logger.debug("Running method '#{method_name}'...")
else
@logger.warn("Retrying method '#{method_name}', #{i} attempts so far...")
end
begin
status, object = @stub_adapter.invoke_method(managed_object, method_info, arguments, self)
rescue URI::Error,
SocketError,
Errno::ECONNREFUSED,
Errno::ETIMEDOUT,
Errno::ECONNRESET,
Timeout::Error,
HTTPClient::TimeoutError,
HTTPClient::KeepAliveDisconnected,
OpenSSL::SSL::SSLError,
OpenSSL::X509::StoreError => e
@logger.warn("Error running method '#{method_name}'. Failed with '#{e.class}: #{e.message}'")
err = e
else
if status.between?(200, 299)
result = object
elsif object.kind_of?(VimSdk::Vmodl::MethodFault)
err = VimSdk::SoapError.new(object.msg, object)
else
err = VimSdk::SoapError.new('Unknown SOAP fault', object)
end
if err
@logger.warn(fault_message(method_name, err))
unless @retry_judge.retryable?(managed_object, method_info.wsdl_name, object)
raise err
end
end
end
[result, err]
end
method_result
end
def invoke_property(managed_object, property_info)
@stub_adapter.invoke_property(managed_object, property_info, self)
end
def version
@stub_adapter.version
end
private
def fault_message(method_name, err)
msg = "Error running method '#{method_name}'. Failed with message '#{err.message}'"
if err.fault && err.fault.fault_cause
msg += " and cause '#{err.fault.fault_cause}'"
end
msg << '.'
msg
end
end
end
end