gapic-common 1.4.0 → 1.5.0

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.
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2026 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Gapic
18
+ module Rest
19
+ module ResumableUpload
20
+ ##
21
+ # @private
22
+ # Event vocabulary emitted by the Driver and dispatched to Core/Rules.
23
+ # Events are `outside-in` signaling. Something happened, e.g. a chunk of data
24
+ # was successfully read, and the Driver is reporting that to Core/Rules.
25
+ #
26
+ module Event
27
+ ##
28
+ # @private
29
+ # Signals the start of the upload session.
30
+ #
31
+ StartUpload = Data.define
32
+
33
+ ##
34
+ # @private
35
+ # Signals the resumption of an existing upload session.
36
+ #
37
+ ResumeUpload = Data.define
38
+
39
+ ##
40
+ # @private
41
+ # Signals that binary data was read from the stream into the Driver's buffer.
42
+ #
43
+ # @!attribute [r] bytes_buffered
44
+ # @return [Integer] Number of bytes currently held in the Driver buffer
45
+ # @!attribute [r] eof
46
+ # @return [Boolean] Whether stream EOF was encountered during the read
47
+ #
48
+ ChunkRead = Data.define :bytes_buffered, :eof do
49
+ ##
50
+ # @private
51
+ # Initializes a ChunkRead event.
52
+ #
53
+ # @param bytes_buffered [Integer] Number of bytes currently held in buffer
54
+ # @param eof [Boolean] Whether stream EOF was encountered
55
+ #
56
+ def initialize bytes_buffered: 0, eof: false
57
+ super bytes_buffered: bytes_buffered, eof: eof
58
+ end
59
+ end
60
+
61
+ ##
62
+ # @private
63
+ # Signals a completed HTTP exchange over the wire (status, headers, body, error).
64
+ #
65
+ # @!attribute [r] status
66
+ # @return [Integer] HTTP status code
67
+ # @!attribute [r] headers
68
+ # @return [Hash<String, String>] Response headers
69
+ # @!attribute [r] body
70
+ # @return [String, nil] Response body
71
+ # @!attribute [r] error
72
+ # @return [Gapic::Rest::Error, nil] Wrapped REST error if status >= 400
73
+ #
74
+ HttpResponse = Data.define :status, :headers, :body, :error do
75
+ ##
76
+ # @private
77
+ # Initializes an HttpResponse event.
78
+ #
79
+ # @param status [Integer] HTTP status code
80
+ # @param headers [Hash<String, String>] Response headers
81
+ # @param body [String, nil] Response body
82
+ # @param error [Gapic::Rest::Error, nil] Wrapped REST error
83
+ #
84
+ def initialize status:, headers: {}, body: nil, error: nil
85
+ super status: status, headers: headers || {}, body: body, error: error
86
+ end
87
+ end
88
+
89
+ ##
90
+ # @private
91
+ # Signals an HTTP request failure (e.g. request timeout, transport connection failure, or retries exhausted).
92
+ #
93
+ # @!attribute [r] kind
94
+ # @return [Symbol] Failure kind: `:timeout`, `:connection_failed`, `:retries_exhausted` (a transport
95
+ # error of no more specific kind), or `:unknown` (a non-transport error, e.g. a credentials failure)
96
+ # @!attribute [r] message
97
+ # @return [String, nil] Human-readable failure summary
98
+ # @!attribute [r] source_error
99
+ # @return [StandardError, nil] Original underlying exception
100
+ #
101
+ RequestFailed = Data.define :kind, :message, :source_error do
102
+ ##
103
+ # @private
104
+ # Initializes a RequestFailed event.
105
+ #
106
+ # @param kind [Symbol] Failure kind (`:timeout`, `:connection_failed`, `:retries_exhausted`, `:unknown`)
107
+ # @param message [String, nil] Human-readable failure summary
108
+ # @param source_error [StandardError, nil] Original underlying exception
109
+ #
110
+ def initialize kind:, message: nil, source_error: nil
111
+ super kind: kind, message: message, source_error: source_error
112
+ end
113
+ end
114
+
115
+ ##
116
+ # @private
117
+ # Signals a caller-requested session cancellation.
118
+ #
119
+ Cancel = Data.define
120
+
121
+ ##
122
+ # @private
123
+ # Signals that the global monotonic clock exceeded the configured deadline.
124
+ #
125
+ GlobalDeadlineExceeded = Data.define
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,273 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2026 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Gapic
18
+ module Rest
19
+ module ResumableUpload
20
+ ##
21
+ # @private
22
+ # Instruction vocabulary emitted by Rules/Core to be executed by Driver.
23
+ # The vocabulary is partitioned three ways ({CONTINUATION}, {TERMINAL}, {SIDE_EFFECT}),
24
+ # and every instruction class must join exactly one list.
25
+ #
26
+ module Instruction
27
+ ##
28
+ # @private
29
+ # Execute initiation request to establish upload session.
30
+ #
31
+ # @!attribute [r] url
32
+ # @return [String] Initial endpoint URI
33
+ # @!attribute [r] headers
34
+ # @return [Hash<String, String>] Additional headers for initiation request
35
+ # @!attribute [r] body
36
+ # @return [String, nil] Request payload for session initiation
37
+ #
38
+ SendStart = Data.define :url, :headers, :body do
39
+ ##
40
+ # @private
41
+ # Initializes a SendStart instruction.
42
+ #
43
+ # @param url [String] Initial endpoint URI
44
+ # @param headers [Hash<String, String>] Additional headers
45
+ # @param body [String, nil] Request payload
46
+ #
47
+ def initialize url:, headers: {}, body: nil
48
+ super url: url, headers: headers || {}, body: body
49
+ end
50
+ end
51
+
52
+ ##
53
+ # @private
54
+ # Transmit buffered chunk starting at offset for length bytes.
55
+ #
56
+ # @!attribute [r] url
57
+ # @return [String] Session upload URL
58
+ # @!attribute [r] offset
59
+ # @return [Integer] Byte offset within the full upload stream
60
+ # @!attribute [r] length
61
+ # @return [Integer] Number of bytes to transmit from buffer
62
+ # @!attribute [r] finalize
63
+ # @return [Boolean] Whether to append finalize command to upload request
64
+ #
65
+ SendChunk = Data.define :url, :offset, :length, :finalize do
66
+ ##
67
+ # @private
68
+ # Initializes a SendChunk instruction.
69
+ #
70
+ # @param url [String] Session upload URL
71
+ # @param offset [Integer] Byte offset within upload stream
72
+ # @param length [Integer] Number of bytes to transmit
73
+ # @param finalize [Boolean] Whether to combine upload and finalize commands
74
+ #
75
+ def initialize url:, offset:, length:, finalize: false
76
+ super url: url, offset: offset, length: length, finalize: finalize
77
+ end
78
+ end
79
+
80
+ ##
81
+ # @private
82
+ # Send standalone finalize command when all data bytes were already uploaded.
83
+ #
84
+ # @!attribute [r] url
85
+ # @return [String] Session upload URL
86
+ #
87
+ SendFinalize = Data.define :url do
88
+ ##
89
+ # @private
90
+ # Initializes a SendFinalize instruction.
91
+ #
92
+ # @param url [String] Session upload URL
93
+ #
94
+ def initialize url:
95
+ super url: url
96
+ end
97
+ end
98
+
99
+ ##
100
+ # @private
101
+ # Query backend for current acknowledged offset.
102
+ #
103
+ # Every query belongs to a recovery episode (see {State#recovery_offset}). The Driver keeps one
104
+ # `Gapic::Common::RetryPolicy` per episode and uses it both between attempts of a single query and
105
+ # between queries, so the delay grows across the whole episode instead of restarting per command.
106
+ #
107
+ # @!attribute [r] url
108
+ # @return [String] Session upload URL
109
+ # @!attribute [r] backoff
110
+ # @return [Boolean] `false` to open a new recovery episode and send at once; `true` to continue the
111
+ # open episode, waiting for its next backoff delay before sending
112
+ #
113
+ SendQuery = Data.define :url, :backoff do
114
+ ##
115
+ # @private
116
+ # Initializes a SendQuery instruction.
117
+ #
118
+ # @param url [String] Session upload URL
119
+ # @param backoff [Boolean] Whether to continue the open recovery episode after its next backoff delay
120
+ #
121
+ def initialize url:, backoff: false
122
+ super url: url, backoff: backoff
123
+ end
124
+ end
125
+
126
+ ##
127
+ # @private
128
+ # Cancel upload session on backend.
129
+ #
130
+ # @!attribute [r] url
131
+ # @return [String] Session upload URL
132
+ #
133
+ SendCancel = Data.define :url do
134
+ ##
135
+ # @private
136
+ # Initializes a SendCancel instruction.
137
+ #
138
+ # @param url [String] Session upload URL
139
+ #
140
+ def initialize url:
141
+ super url: url
142
+ end
143
+ end
144
+
145
+ ##
146
+ # @private
147
+ # Realign Driver in-memory buffer and stream position to match server_offset.
148
+ #
149
+ # @!attribute [r] server_offset
150
+ # @return [Integer] Acknowledged byte offset reported by server
151
+ #
152
+ RealignBuffer = Data.define :server_offset do
153
+ ##
154
+ # @private
155
+ # Initializes a RealignBuffer instruction.
156
+ #
157
+ # @param server_offset [Integer] Target server byte offset
158
+ #
159
+ def initialize server_offset:
160
+ super server_offset: server_offset
161
+ end
162
+ end
163
+
164
+ ##
165
+ # @private
166
+ # Read from stream until in-memory buffer reaches target_bytesize or stream hits EOF.
167
+ #
168
+ # @!attribute [r] target_bytesize
169
+ # @return [Integer] Target buffer size in bytes
170
+ #
171
+ FillBuffer = Data.define :target_bytesize do
172
+ ##
173
+ # @private
174
+ # Initializes a FillBuffer instruction.
175
+ #
176
+ # @param target_bytesize [Integer] Target buffer size in bytes
177
+ #
178
+ def initialize target_bytesize:
179
+ super target_bytesize: target_bytesize
180
+ end
181
+ end
182
+
183
+ ##
184
+ # @private
185
+ # Invoke user progress callback with a Progress instance.
186
+ #
187
+ # @!attribute [r] progress
188
+ # @return [Gapic::Rest::ResumableUpload::Progress] Progress notification snapshot
189
+ #
190
+ NotifyProgress = Data.define :progress do
191
+ ##
192
+ # @private
193
+ # Initializes a NotifyProgress instruction.
194
+ #
195
+ # @param progress [Gapic::Rest::ResumableUpload::Progress] Progress notification snapshot
196
+ #
197
+ def initialize progress:
198
+ super progress: progress
199
+ end
200
+ end
201
+
202
+ ##
203
+ # @private
204
+ # Upload finalized cleanly; return response.
205
+ #
206
+ # @!attribute [r] response
207
+ # @return [Gapic::Rest::ResumableUpload::Event::HttpResponse] Final response object
208
+ #
209
+ TerminateSuccess = Data.define :response do
210
+ ##
211
+ # @private
212
+ # Initializes a TerminateSuccess instruction.
213
+ #
214
+ # @param response [Gapic::Rest::ResumableUpload::Event::HttpResponse] Final response object
215
+ #
216
+ def initialize response:
217
+ super response: response
218
+ end
219
+ end
220
+
221
+ ##
222
+ # @private
223
+ # Terminate upload with error.
224
+ #
225
+ # @!attribute [r] error
226
+ # @return [StandardError] Terminal exception to raise
227
+ #
228
+ TerminateFailure = Data.define :error do
229
+ ##
230
+ # @private
231
+ # Initializes a TerminateFailure instruction.
232
+ #
233
+ # @param error [StandardError] Terminal exception to raise
234
+ #
235
+ def initialize error:
236
+ super error: error
237
+ end
238
+ end
239
+
240
+ ##
241
+ # @private
242
+ # Instruction classes that produce a continuation event for the next step of the trampoline loop.
243
+ # @return [Array<Class>]
244
+ CONTINUATION = [
245
+ FillBuffer,
246
+ SendStart,
247
+ SendChunk,
248
+ SendFinalize,
249
+ SendQuery,
250
+ SendCancel
251
+ ].freeze
252
+
253
+ ##
254
+ # @private
255
+ # Instruction classes that terminate the upload run.
256
+ # @return [Array<Class>]
257
+ TERMINAL = [
258
+ TerminateSuccess,
259
+ TerminateFailure
260
+ ].freeze
261
+
262
+ ##
263
+ # @private
264
+ # Instruction classes that perform side effects without producing continuation events or terminating.
265
+ # @return [Array<Class>]
266
+ SIDE_EFFECT = [
267
+ NotifyProgress,
268
+ RealignBuffer
269
+ ].freeze
270
+ end
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2026 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "gapic/common/error_codes"
18
+ require "gapic/common/retry_policy"
19
+ require "gapic/rest/resumable_upload/rules"
20
+
21
+ module Gapic
22
+ module Rest
23
+ module ResumableUpload
24
+ ##
25
+ # @private
26
+ # Default retry policy generators for control plane and data plane requests.
27
+ #
28
+ # The defaults carry no `retry_predicate`: every protocol-specific retry decision lives in
29
+ # {Driver::RetryDecider}, which consults a policy only for its budget and backoff, and for the
30
+ # caller-facing `retry_predicate` and `retry_codes`. The `retry_codes` below are derived from the HTTP
31
+ # status sets on {Rules}, so HTTP status is the single source of truth.
32
+ #
33
+ # Keep in sync with the "Retry Policies" section of the {Gapic::ResumableUpload} class doc.
34
+ #
35
+ module RetryPolicies
36
+ ##
37
+ # @private
38
+ # Default `retry_codes` for initiation, `query` and `cancel`: 409, 429, 499, 500, 503 and 504.
39
+ # @return [Array<Integer>]
40
+ START_AND_CONTROL_PLANE_RETRY_CODES =
41
+ (Rules::RETRIABLE_4XX_STATUS_CODES + Rules::RETRIABLE_5XX_STATUS_CODES).map do |status|
42
+ Gapic::Common::ErrorCodes.grpc_error_for status
43
+ end.freeze
44
+
45
+ ##
46
+ # @private
47
+ # Default `retry_codes` for `upload` and `finalize`: 500, 503 and 504. The data plane never
48
+ # retries a 4xx, so none is listed.
49
+ # @return [Array<Integer>]
50
+ DATA_PLANE_RETRY_CODES = Rules::RETRIABLE_5XX_STATUS_CODES.map do |status|
51
+ Gapic::Common::ErrorCodes.grpc_error_for status
52
+ end.freeze
53
+
54
+ ##
55
+ # @private
56
+ # Default options for start command retry policy.
57
+ # @return [Hash]
58
+ START_DEFAULTS = {
59
+ retry_codes: START_AND_CONTROL_PLANE_RETRY_CODES,
60
+ initial_delay: 1.0,
61
+ max_delay: 15.0,
62
+ multiplier: 1.3
63
+ }.freeze
64
+
65
+ ##
66
+ # @private
67
+ # Default options for query and cancel commands retry policy.
68
+ # @return [Hash]
69
+ CONTROL_PLANE_DEFAULTS = {
70
+ retry_codes: START_AND_CONTROL_PLANE_RETRY_CODES,
71
+ initial_delay: 1.0,
72
+ max_delay: 15.0,
73
+ multiplier: 1.3
74
+ }.freeze
75
+
76
+ ##
77
+ # @private
78
+ # Default options for upload and finalize commands retry policy.
79
+ # @return [Hash]
80
+ DATA_PLANE_DEFAULTS = {
81
+ retry_codes: DATA_PLANE_RETRY_CODES,
82
+ initial_delay: 1.0,
83
+ max_delay: 15.0,
84
+ multiplier: 1.3
85
+ }.freeze
86
+
87
+ ##
88
+ # @private
89
+ # Default retry policy for session initiation requests (start).
90
+ #
91
+ # @return [Gapic::Common::RetryPolicy]
92
+ def self.default_start
93
+ Gapic::Common::RetryPolicy.new(**START_DEFAULTS)
94
+ end
95
+
96
+ ##
97
+ # @private
98
+ # Default retry policy for session control requests (query, cancel).
99
+ #
100
+ # @return [Gapic::Common::RetryPolicy]
101
+ def self.default_control_plane
102
+ Gapic::Common::RetryPolicy.new(**CONTROL_PLANE_DEFAULTS)
103
+ end
104
+
105
+ ##
106
+ # @private
107
+ # Default retry policy for data plane requests (upload, finalize).
108
+ #
109
+ # @return [Gapic::Common::RetryPolicy]
110
+ def self.default_data_plane
111
+ Gapic::Common::RetryPolicy.new(**DATA_PLANE_DEFAULTS)
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end