cassandra-driver 2.1.7-java → 3.0.0.beta.1-java
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.
- checksums.yaml +4 -4
- data/README.md +31 -53
- data/lib/cassandra.rb +22 -3
- data/lib/cassandra/aggregate.rb +109 -0
- data/lib/cassandra/argument.rb +51 -0
- data/lib/cassandra/auth/providers/password.rb +7 -4
- data/lib/cassandra/cluster.rb +14 -3
- data/lib/cassandra/cluster/client.rb +56 -34
- data/lib/cassandra/cluster/connector.rb +6 -6
- data/lib/cassandra/cluster/control_connection.rb +204 -251
- data/lib/cassandra/cluster/metadata.rb +2 -0
- data/lib/cassandra/cluster/schema.rb +131 -209
- data/lib/cassandra/cluster/schema/cql_type_parser.rb +104 -0
- data/lib/cassandra/cluster/schema/fetchers.rb +1174 -0
- data/lib/cassandra/cluster/schema/{type_parser.rb → fqcn_type_parser.rb} +7 -3
- data/lib/cassandra/column.rb +2 -2
- data/lib/cassandra/driver.rb +27 -9
- data/lib/cassandra/errors.rb +179 -25
- data/lib/cassandra/execution/info.rb +8 -1
- data/lib/cassandra/execution/options.rb +34 -0
- data/lib/cassandra/execution/trace.rb +42 -10
- data/lib/cassandra/function.rb +150 -0
- data/lib/cassandra/future.rb +66 -35
- data/lib/cassandra/host.rb +7 -4
- data/lib/cassandra/keyspace.rb +112 -13
- data/lib/cassandra/load_balancing.rb +1 -1
- data/lib/cassandra/protocol.rb +9 -3
- data/lib/cassandra/protocol/coder.rb +434 -155
- data/lib/cassandra/protocol/cql_byte_buffer.rb +43 -0
- data/lib/cassandra/protocol/cql_protocol_handler.rb +4 -1
- data/lib/cassandra/protocol/request.rb +4 -0
- data/lib/cassandra/protocol/requests/auth_response_request.rb +5 -1
- data/lib/cassandra/protocol/requests/batch_request.rb +7 -2
- data/lib/cassandra/protocol/requests/credentials_request.rb +5 -1
- data/lib/cassandra/protocol/requests/execute_request.rb +16 -10
- data/lib/cassandra/protocol/requests/prepare_request.rb +12 -3
- data/lib/cassandra/protocol/requests/query_request.rb +20 -11
- data/lib/cassandra/protocol/responses/already_exists_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/error_response.rb +14 -14
- data/lib/cassandra/protocol/responses/function_failure_error_response.rb +41 -0
- data/lib/cassandra/protocol/responses/prepared_result_response.rb +12 -9
- data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +5 -3
- data/lib/cassandra/protocol/responses/read_failure_error_response.rb +43 -0
- data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/ready_response.rb +5 -1
- data/lib/cassandra/protocol/responses/result_response.rb +3 -3
- data/lib/cassandra/protocol/responses/rows_result_response.rb +2 -2
- data/lib/cassandra/protocol/responses/schema_change_event_response.rb +25 -24
- data/lib/cassandra/protocol/responses/schema_change_result_response.rb +20 -23
- data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +2 -2
- data/lib/cassandra/protocol/responses/unavailable_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/unprepared_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/write_failure_error_response.rb +45 -0
- data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +4 -4
- data/lib/cassandra/protocol/v1.rb +38 -13
- data/lib/cassandra/protocol/v3.rb +34 -29
- data/lib/cassandra/protocol/v4.rb +334 -0
- data/lib/cassandra/result.rb +10 -9
- data/lib/cassandra/retry.rb +17 -3
- data/lib/cassandra/retry/policies/default.rb +9 -3
- data/lib/cassandra/session.rb +15 -7
- data/lib/cassandra/statement.rb +5 -0
- data/lib/cassandra/statements/batch.rb +36 -12
- data/lib/cassandra/statements/bound.rb +2 -1
- data/lib/cassandra/statements/prepared.rb +106 -35
- data/lib/cassandra/statements/simple.rb +4 -2
- data/lib/cassandra/table.rb +70 -105
- data/lib/cassandra/time.rb +98 -0
- data/lib/cassandra/time_uuid.rb +1 -1
- data/lib/cassandra/tuple.rb +7 -0
- data/lib/cassandra/types.rb +472 -272
- data/lib/cassandra/udt.rb +10 -0
- data/lib/cassandra/util.rb +32 -1
- data/lib/cassandra/uuid.rb +6 -1
- data/lib/cassandra/uuid/generator.rb +7 -7
- data/lib/cassandra/version.rb +1 -1
- data/lib/cassandra_murmur3.jar +0 -0
- data/lib/datastax/cassandra.rb +5 -2
- metadata +27 -17
@@ -49,6 +49,19 @@ module Cassandra
|
|
49
49
|
# @see Cassandra::Result#paging_state
|
50
50
|
attr_reader :paging_state
|
51
51
|
|
52
|
+
# @return [nil, Hash<String, String>] custom outgoing payload, a map of
|
53
|
+
# string and byte buffers.
|
54
|
+
#
|
55
|
+
# @see https://github.com/apache/cassandra/blob/33f1edcce97779c971d4f78712a9a8bf014ffbbc/doc/native_protocol_v4.spec#L127-L133 Description of custom payload in Cassandra native protocol v4.
|
56
|
+
# @see https://datastax.github.io/java-driver/features/custom_payloads/#enabling-custom-payloads-on-c-nodes Enabling custom payloads on Cassandra nodes.
|
57
|
+
#
|
58
|
+
# @example Sending a custom payload
|
59
|
+
# result = session.execute(payload: {
|
60
|
+
# 'some key' => Cassandra::Protocol::CqlByteBuffer.new
|
61
|
+
# .append_string('some value')
|
62
|
+
# })
|
63
|
+
attr_reader :payload
|
64
|
+
|
52
65
|
# @private
|
53
66
|
def initialize(options)
|
54
67
|
consistency = options[:consistency]
|
@@ -59,6 +72,8 @@ module Cassandra
|
|
59
72
|
paging_state = options[:paging_state]
|
60
73
|
arguments = options[:arguments]
|
61
74
|
type_hints = options[:type_hints]
|
75
|
+
idempotent = options[:idempotent]
|
76
|
+
payload = options[:payload]
|
62
77
|
|
63
78
|
Util.assert_one_of(CONSISTENCIES, consistency) { ":consistency must be one of #{CONSISTENCIES.inspect}, #{consistency.inspect} given" }
|
64
79
|
|
@@ -94,6 +109,17 @@ module Cassandra
|
|
94
109
|
Util.assert_instance_of_one_of([::Array, ::Hash], type_hints) { ":type_hints must be an Array or a Hash, #{type_hints.inspect} given" }
|
95
110
|
end
|
96
111
|
|
112
|
+
unless payload.nil?
|
113
|
+
Util.assert_instance_of(::Hash, payload) { ":payload must be a Hash" }
|
114
|
+
Util.assert_not_empty(payload) { ":payload must not be empty" }
|
115
|
+
Util.assert(payload.size <= 65535) { ":payload cannot contain more than 65535 key/value pairs" }
|
116
|
+
|
117
|
+
payload = payload.each_with_object(::Hash.new) do |(key, value), payload|
|
118
|
+
payload[String(key)] = String(value)
|
119
|
+
end
|
120
|
+
payload.freeze
|
121
|
+
end
|
122
|
+
|
97
123
|
@consistency = consistency
|
98
124
|
@page_size = page_size
|
99
125
|
@trace = !!trace
|
@@ -102,6 +128,8 @@ module Cassandra
|
|
102
128
|
@paging_state = paging_state
|
103
129
|
@arguments = arguments
|
104
130
|
@type_hints = type_hints
|
131
|
+
@idempotent = !!idempotent
|
132
|
+
@payload = payload
|
105
133
|
end
|
106
134
|
|
107
135
|
# @return [Boolean] whether request tracing was enabled
|
@@ -109,6 +137,12 @@ module Cassandra
|
|
109
137
|
@trace
|
110
138
|
end
|
111
139
|
|
140
|
+
# @return [Boolean] whether statement can be retried on timeout
|
141
|
+
def idempotent?
|
142
|
+
@idempotent
|
143
|
+
end
|
144
|
+
|
145
|
+
# @private
|
112
146
|
def eql?(other)
|
113
147
|
other.is_a?(Options) &&
|
114
148
|
other.consistency == @consistency &&
|
@@ -39,6 +39,7 @@ module Cassandra
|
|
39
39
|
@thread = thread
|
40
40
|
end
|
41
41
|
|
42
|
+
# @private
|
42
43
|
def ==(other)
|
43
44
|
other == @id
|
44
45
|
end
|
@@ -53,41 +54,61 @@ module Cassandra
|
|
53
54
|
|
54
55
|
# @private
|
55
56
|
def initialize(id, client)
|
56
|
-
@id
|
57
|
-
@client
|
57
|
+
@id = id
|
58
|
+
@client = client
|
59
|
+
@coordinator = nil
|
60
|
+
@duration = nil
|
61
|
+
@parameters = nil
|
62
|
+
@request = nil
|
63
|
+
@started_at = nil
|
64
|
+
@events = nil
|
65
|
+
@client_ip = nil
|
66
|
+
@loaded = false
|
67
|
+
@loaded_events = false
|
58
68
|
|
59
69
|
mon_initialize
|
60
70
|
end
|
61
71
|
|
62
|
-
# Returns the ip of coordinator node. Typically the same as
|
72
|
+
# Returns the ip of coordinator node. Typically the same as
|
73
|
+
# {Cassandra::Execution::Info#hosts}`.last`
|
63
74
|
#
|
64
75
|
# @return [IPAddr] ip of the coordinator node
|
65
76
|
def coordinator
|
66
|
-
load unless @
|
77
|
+
load unless @loaded
|
67
78
|
|
68
79
|
@coordinator
|
69
80
|
end
|
70
81
|
|
82
|
+
# Returns the ip of the client node, the node that ran the driver
|
83
|
+
# instance that started tracing.
|
84
|
+
#
|
85
|
+
# @return [IPAddr, nil] ip of the client node running the driver
|
86
|
+
def client
|
87
|
+
load unless @loaded
|
88
|
+
|
89
|
+
@client_ip
|
90
|
+
end
|
91
|
+
|
71
92
|
def duration
|
72
|
-
load unless @
|
93
|
+
load unless @loaded
|
73
94
|
|
74
95
|
@duration
|
75
96
|
end
|
76
97
|
|
77
98
|
def parameters
|
78
|
-
load unless @
|
99
|
+
load unless @loaded
|
79
100
|
|
80
101
|
@parameters
|
81
102
|
end
|
82
103
|
|
83
104
|
def request
|
84
|
-
load unless @
|
105
|
+
load unless @loaded
|
85
106
|
|
86
107
|
@request
|
87
108
|
end
|
88
109
|
|
89
110
|
def started_at
|
90
|
-
load unless @
|
111
|
+
load unless @loaded
|
91
112
|
|
92
113
|
@started_at
|
93
114
|
end
|
@@ -96,11 +117,12 @@ module Cassandra
|
|
96
117
|
#
|
97
118
|
# @return [Array<Cassandra::Execution::Trace::Event>] events
|
98
119
|
def events
|
99
|
-
load_events unless @
|
120
|
+
load_events unless @loaded_events
|
100
121
|
|
101
122
|
@events
|
102
123
|
end
|
103
124
|
|
125
|
+
# @private
|
104
126
|
def inspect
|
105
127
|
"#<#{self.class.name}:0x#{self.object_id.to_s(16)} @id=#{@id.inspect}>"
|
106
128
|
end
|
@@ -117,7 +139,16 @@ module Cassandra
|
|
117
139
|
synchronize do
|
118
140
|
return if @loaded
|
119
141
|
|
120
|
-
|
142
|
+
attempt = 1
|
143
|
+
data = @client.query(Statements::Simple.new(SELECT_SESSION % @id), VOID_OPTIONS).get.first
|
144
|
+
|
145
|
+
while data.nil? && attempt <= 5
|
146
|
+
sleep(attempt * 0.4)
|
147
|
+
data = @client.query(Statements::Simple.new(SELECT_SESSION % @id), VOID_OPTIONS).get.first
|
148
|
+
break if data
|
149
|
+
attempt += 1
|
150
|
+
end
|
151
|
+
|
121
152
|
raise ::RuntimeError, "unable to load trace #{@id}" if data.nil?
|
122
153
|
|
123
154
|
@coordinator = data['coordinator']
|
@@ -125,6 +156,7 @@ module Cassandra
|
|
125
156
|
@parameters = data['parameters']
|
126
157
|
@request = data['request']
|
127
158
|
@started_at = data['started_at']
|
159
|
+
@client_ip = data['client']
|
128
160
|
@loaded = true
|
129
161
|
end
|
130
162
|
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2013-2015 DataStax, Inc.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#++
|
18
|
+
|
19
|
+
module Cassandra
|
20
|
+
# Represents a cassandra user defined function
|
21
|
+
# @see Cassandra::Keyspace#each_function
|
22
|
+
# @see Cassandra::Keyspace#function
|
23
|
+
# @see Cassandra::Keyspace#has_function?
|
24
|
+
class Function
|
25
|
+
# @private
|
26
|
+
attr_reader :keyspace
|
27
|
+
# @return [String] function name
|
28
|
+
attr_reader :name
|
29
|
+
# @return [String] function language
|
30
|
+
attr_reader :language
|
31
|
+
# @return [Cassandra::Type] function return type
|
32
|
+
attr_reader :type
|
33
|
+
# @return [String] function body
|
34
|
+
attr_reader :body
|
35
|
+
|
36
|
+
# @private
|
37
|
+
def initialize(keyspace, name, language, type, arguments, body, called_on_null)
|
38
|
+
@keyspace = keyspace
|
39
|
+
@name = name
|
40
|
+
@language = language
|
41
|
+
@type = type
|
42
|
+
@arguments = arguments
|
43
|
+
@body = body
|
44
|
+
@called_on_null = called_on_null
|
45
|
+
|
46
|
+
# Build up an arguments hash keyed on arg-name.
|
47
|
+
@arguments_hash = @arguments.each_with_object({}) do |arg, h|
|
48
|
+
h[arg.name] = arg
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Boolean] whether this function will be called on null input
|
53
|
+
def called_on_null?
|
54
|
+
@called_on_null
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param name [String] argument name
|
58
|
+
# @return [Boolean] whether this function has a given argument
|
59
|
+
def has_argument?(name)
|
60
|
+
@arguments_hash.has_key?(name)
|
61
|
+
end
|
62
|
+
|
63
|
+
# @param name [String] argument name
|
64
|
+
# @return [Cassandra::Argument, nil] an argument or nil
|
65
|
+
def argument(name)
|
66
|
+
@arguments_hash[name]
|
67
|
+
end
|
68
|
+
|
69
|
+
# Yield or enumerate each argument defined in this function
|
70
|
+
# @overload each_argument
|
71
|
+
# @yieldparam argument [Cassandra::Argument] current argument
|
72
|
+
# @return [Cassandra::Table] self
|
73
|
+
# @overload each_argument
|
74
|
+
# @return [Array<Cassandra::Argument>] a list of arguments
|
75
|
+
def each_argument(&block)
|
76
|
+
if block_given?
|
77
|
+
@arguments.each(&block)
|
78
|
+
self
|
79
|
+
else
|
80
|
+
# We return a dup of the arguments so that the caller can manipulate
|
81
|
+
# the array however they want without affecting the source.
|
82
|
+
@arguments.dup
|
83
|
+
end
|
84
|
+
end
|
85
|
+
alias :arguments :each_argument
|
86
|
+
|
87
|
+
# Get the list of argument types for this function.
|
88
|
+
# @return [Array<Cassandra::Type>] a list of argument types.
|
89
|
+
def argument_types
|
90
|
+
@arguments.map { |argument| argument.type }
|
91
|
+
end
|
92
|
+
|
93
|
+
# @private
|
94
|
+
def eql?(other)
|
95
|
+
other.is_a?(Function) && \
|
96
|
+
@keyspace == other.keyspace && \
|
97
|
+
@name == other.name && \
|
98
|
+
@language == other.language && \
|
99
|
+
@type == other.type && \
|
100
|
+
@arguments == other.arguments && \
|
101
|
+
@body == other.body && \
|
102
|
+
@called_on_null == other.called_on_null?
|
103
|
+
end
|
104
|
+
alias :== :eql?
|
105
|
+
|
106
|
+
# @private
|
107
|
+
def hash
|
108
|
+
@hash ||= begin
|
109
|
+
h = 17
|
110
|
+
h = 31 * h + @keyspace.hash
|
111
|
+
h = 31 * h + @name.hash
|
112
|
+
h = 31 * h + @language.hash
|
113
|
+
h = 31 * h + @type.hash
|
114
|
+
h = 31 * h + @arguments.hash
|
115
|
+
h = 31 * h + @body.hash
|
116
|
+
h = 31 * h + @called_on_null.hash
|
117
|
+
h
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# @private
|
122
|
+
def inspect
|
123
|
+
"#<Cassandra::Function:0x#{self.object_id.to_s(16)} @keyspace=#{@keyspace.inspect}, @name=#{@name.inspect}, @language=#{@language.inspect}, @type=#{@type.inspect}, @arguments=#{@arguments.inspect} @body=#{@body.inspect}>"
|
124
|
+
end
|
125
|
+
|
126
|
+
# @return [String] a cql representation of this function
|
127
|
+
def to_cql
|
128
|
+
cql = "CREATE FUNCTION #{Util.escape_name(@keyspace)}.#{Util.escape_name(@name)}("
|
129
|
+
first = true
|
130
|
+
@arguments.each do |argument|
|
131
|
+
if first
|
132
|
+
first = false
|
133
|
+
else
|
134
|
+
cql << ', '
|
135
|
+
end
|
136
|
+
cql << "#{argument.name} #{argument.type}"
|
137
|
+
end
|
138
|
+
cql << ")"
|
139
|
+
if @called_on_null
|
140
|
+
cql << "\n CALLED ON NULL INPUT"
|
141
|
+
else
|
142
|
+
cql << "\n RETURNS NULL ON NULL INPUT"
|
143
|
+
end
|
144
|
+
cql << "\n RETURNS #{@type}"
|
145
|
+
cql << "\n LANGUAGE #{@language}"
|
146
|
+
cql << "\n AS $$#{@body}$$"
|
147
|
+
cql << ";"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
data/lib/cassandra/future.rb
CHANGED
@@ -51,10 +51,12 @@ module Cassandra
|
|
51
51
|
@error = error
|
52
52
|
end
|
53
53
|
|
54
|
-
def get
|
54
|
+
def get(timeout = nil)
|
55
55
|
raise(@error, @error.message, @error.backtrace)
|
56
56
|
end
|
57
57
|
|
58
|
+
alias :join :get
|
59
|
+
|
58
60
|
def on_success
|
59
61
|
raise ::ArgumentError, "no block given" unless block_given?
|
60
62
|
self
|
@@ -81,10 +83,6 @@ module Cassandra
|
|
81
83
|
self
|
82
84
|
end
|
83
85
|
|
84
|
-
def join
|
85
|
-
self
|
86
|
-
end
|
87
|
-
|
88
86
|
def then
|
89
87
|
raise ::ArgumentError, "no block given" unless block_given?
|
90
88
|
self
|
@@ -109,10 +107,12 @@ module Cassandra
|
|
109
107
|
@value = value
|
110
108
|
end
|
111
109
|
|
112
|
-
def get
|
110
|
+
def get(timeout = nil)
|
113
111
|
@value
|
114
112
|
end
|
115
113
|
|
114
|
+
alias :join :get
|
115
|
+
|
116
116
|
def on_success
|
117
117
|
raise ::ArgumentError, "no block given" unless block_given?
|
118
118
|
yield(@value) rescue nil
|
@@ -356,23 +356,23 @@ module Cassandra
|
|
356
356
|
end
|
357
357
|
|
358
358
|
# Returns future value or raises future error
|
359
|
-
#
|
360
|
-
# @
|
361
|
-
#
|
362
|
-
|
363
|
-
|
364
|
-
|
359
|
+
#
|
360
|
+
# @note This method blocks until a future is resolved or a times out
|
361
|
+
#
|
362
|
+
# @param timeout [nil, Numeric] a maximum number of seconds to block
|
363
|
+
# current thread for while waiting for this future to resolve. Will
|
364
|
+
# wait indefinitely if passed `nil`.
|
365
|
+
#
|
366
|
+
# @raise [Errors::TimeoutError] raised when wait time exceeds the timeout
|
367
|
+
# @raise [Exception] raises when the future has been resolved with an
|
368
|
+
# error. The original exception will be raised.
|
369
|
+
#
|
370
|
+
# @return [Object] the value that the future has been resolved with
|
371
|
+
def get(timeout = nil)
|
372
|
+
@signal.get(timeout)
|
365
373
|
end
|
366
374
|
|
367
|
-
|
368
|
-
# @note This method blocks until a future is resolved
|
369
|
-
# @note This method won't raise any errors or return anything but the
|
370
|
-
# future itself
|
371
|
-
# @return [self]
|
372
|
-
def join
|
373
|
-
@signal.join
|
374
|
-
self
|
375
|
-
end
|
375
|
+
alias :join :get
|
376
376
|
end
|
377
377
|
|
378
378
|
# @private
|
@@ -550,28 +550,59 @@ module Cassandra
|
|
550
550
|
self
|
551
551
|
end
|
552
552
|
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
553
|
+
# @param timeout [nil, Numeric] a maximum number of seconds to block
|
554
|
+
# current thread for while waiting for this future to resolve. Will
|
555
|
+
# wait indefinitely if passed `nil`.
|
556
|
+
#
|
557
|
+
# @raise [ArgumentError] raised when a negative timeout is given
|
558
|
+
# @raise [Errors::TimeoutError] raised when wait time exceeds the timeout
|
559
|
+
# @raise [Exception] raises when the future has been resolved with an
|
560
|
+
# error. The original exception will be raised.
|
561
|
+
#
|
562
|
+
# @return [Object] the value that the future has been resolved with
|
563
|
+
def get(timeout = nil)
|
564
|
+
timeout = timeout && Float(timeout)
|
565
|
+
|
566
|
+
if timeout
|
567
|
+
raise ::ArgumentError, "timeout cannot be negative, #{timeout.inspect} given" if timeout < 0
|
568
|
+
|
569
|
+
start = ::Time.now
|
570
|
+
now = start
|
571
|
+
deadline = start + timeout
|
562
572
|
end
|
563
573
|
|
564
|
-
|
565
|
-
|
574
|
+
if @state == :pending
|
575
|
+
synchronize do
|
576
|
+
if @state == :pending
|
577
|
+
@waiting += 1
|
578
|
+
while @state == :pending
|
579
|
+
if deadline
|
580
|
+
@cond.wait(deadline - now)
|
581
|
+
now = ::Time.now
|
582
|
+
break if now >= deadline
|
583
|
+
else
|
584
|
+
@cond.wait
|
585
|
+
end
|
586
|
+
end
|
587
|
+
@waiting -= 1
|
588
|
+
end
|
589
|
+
end
|
566
590
|
|
567
|
-
|
568
|
-
|
591
|
+
if @state == :pending
|
592
|
+
total_wait = deadline - start
|
593
|
+
raise Errors::TimeoutError, "Future did not complete within #{timeout.inspect} seconds. Wait time: #{total_wait.inspect}"
|
594
|
+
end
|
595
|
+
end
|
569
596
|
|
570
|
-
|
597
|
+
if @state == :broken
|
598
|
+
raise(@error, @error.message, @error.backtrace)
|
599
|
+
end
|
571
600
|
|
572
601
|
@value
|
573
602
|
end
|
574
603
|
|
604
|
+
alias :join :get
|
605
|
+
|
575
606
|
def add_listener(listener)
|
576
607
|
if @state == :pending
|
577
608
|
synchronize do
|