gapic-common 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/gapic/common/version.rb +1 -1
- data/lib/gapic/rest/client_stub.rb +8 -1
- data/lib/gapic/rest/server_stream.rb +101 -0
- data/lib/gapic/rest/threaded_enumerator.rb +71 -0
- data/lib/gapic/rest.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b5964ec91020c76501e2424be598b345a114a16515fe209135e46f552100d4e
|
4
|
+
data.tar.gz: 4a08e08fe15b6c6d6a3ad3097895a7d01bcfe3377f1392946a0cfe671ca97fdf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0270a8d4933fda1f6297233f3465ae4fed20d34ebbf4bb766f228fe13746b5508c97179eb7c0b763d104c52079f59765b514c32a1d6cb2d61196791f007595a
|
7
|
+
data.tar.gz: 437633278a8640eee28a975c7821270b11c2127c72970e0259c29b5b643db37b8d394ac5ae1cd80cb367e10c1384311cc018e0a276804dfda7d8a91f9fffb13a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 0.13.0 (2022-10-26)
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* Implement server-side streaming support for REST calls in gapic-common ([#826](https://github.com/googleapis/gapic-generator-ruby/issues/826))
|
8
|
+
|
3
9
|
### 0.12.0 (2022-09-15)
|
4
10
|
|
5
11
|
#### Features
|
data/lib/gapic/common/version.rb
CHANGED
@@ -127,8 +127,10 @@ module Gapic
|
|
127
127
|
# @param params [Hash] query string parameters for the request
|
128
128
|
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
|
129
129
|
# to the REST call. Currently only timeout and headers are supported.
|
130
|
+
# @param is_server_streaming [Boolean] flag if method is streaming
|
131
|
+
# @yieldparam chunk [String] The chunk of data received during server streaming.
|
130
132
|
# @return [Faraday::Response]
|
131
|
-
def make_http_request verb, uri:, body:, params:, options:
|
133
|
+
def make_http_request verb, uri:, body:, params:, options:, is_server_streaming: false
|
132
134
|
if @numeric_enums && (!params.key?("$alt") || params["$alt"] == "json")
|
133
135
|
params = params.merge({ "$alt" => "json;enum-encoding=int" })
|
134
136
|
end
|
@@ -138,6 +140,11 @@ module Gapic
|
|
138
140
|
req.body = body unless body.nil?
|
139
141
|
req.headers = req.headers.merge options.metadata
|
140
142
|
req.options.timeout = options.timeout if options.timeout&.positive?
|
143
|
+
if is_server_streaming
|
144
|
+
req.options.on_data = proc do |chunk, _overall_received_bytes|
|
145
|
+
yield chunk
|
146
|
+
end
|
147
|
+
end
|
141
148
|
end
|
142
149
|
end
|
143
150
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# Copyright 2022 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require "json"
|
16
|
+
|
17
|
+
module Gapic
|
18
|
+
module Rest
|
19
|
+
##
|
20
|
+
# A class to provide the Enumerable interface to the response of a REST server-streaming dmethod.
|
21
|
+
#
|
22
|
+
# ServerStream provides the enumerations over the individual response messages within the stream.
|
23
|
+
#
|
24
|
+
# @example normal iteration over resources.
|
25
|
+
# server_stream.each { |response| puts response }
|
26
|
+
#
|
27
|
+
class ServerStream
|
28
|
+
include Enumerable
|
29
|
+
|
30
|
+
##
|
31
|
+
# Initializes ServerStream object.
|
32
|
+
#
|
33
|
+
# @param message_klass [Class]
|
34
|
+
# @param json_enumerator [Enumerator<String>]
|
35
|
+
def initialize message_klass, json_enumerator
|
36
|
+
@json_enumerator = json_enumerator
|
37
|
+
@obj = ""
|
38
|
+
@message_klass = message_klass
|
39
|
+
@ready_objs = [] # List of strings
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Iterate over JSON objects in the streamed response.
|
44
|
+
#
|
45
|
+
# @yield [Object] Gives one complete Message object.
|
46
|
+
#
|
47
|
+
# @return [Enumerator] if no block is provided
|
48
|
+
#
|
49
|
+
def each
|
50
|
+
return enum_for :each unless block_given?
|
51
|
+
|
52
|
+
loop do
|
53
|
+
while @ready_objs.length.zero?
|
54
|
+
begin
|
55
|
+
chunk = @json_enumerator.next
|
56
|
+
next unless chunk
|
57
|
+
next_json! chunk
|
58
|
+
rescue StopIteration
|
59
|
+
dangling_content = @obj.strip
|
60
|
+
error_expl = "Dangling content left after iterating through the stream. " \
|
61
|
+
"This means that not all content was received or parsed correctly. " \
|
62
|
+
"It is likely a result of server or network error."
|
63
|
+
error_text = "#{error_expl}\n Content left unparsed: #{dangling_content}"
|
64
|
+
|
65
|
+
raise Gapic::Common::Error, error_text unless dangling_content.empty?
|
66
|
+
return
|
67
|
+
end
|
68
|
+
end
|
69
|
+
yield @message_klass.decode_json @ready_objs.shift, ignore_unknown_fields: true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
##
|
76
|
+
# Builds the next JSON object of the server stream from chunk.
|
77
|
+
#
|
78
|
+
# @param chunk [String] Contains (partial) JSON object
|
79
|
+
#
|
80
|
+
def next_json! chunk
|
81
|
+
chunk.chars.each do |char|
|
82
|
+
# Invariant: @obj is always either a part of a single JSON object or the entire JSON object.
|
83
|
+
# Hence, it's safe to strip whitespace, commans and array brackets. These characters
|
84
|
+
# are only added before @obj is a complete JSON object and essentially can be flushed.
|
85
|
+
next if @obj.empty? && char != "{"
|
86
|
+
@obj += char
|
87
|
+
next unless char == "}"
|
88
|
+
begin
|
89
|
+
# Two choices here: append a Ruby object into
|
90
|
+
# ready_objs or a string. Going with the latter here.
|
91
|
+
JSON.parse @obj
|
92
|
+
@ready_objs.append @obj
|
93
|
+
@obj = ""
|
94
|
+
rescue JSON::ParserError
|
95
|
+
next
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Copyright 2022 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
module Gapic
|
17
|
+
module Rest
|
18
|
+
##
|
19
|
+
# @private
|
20
|
+
# A class to provide the Enumerable interface to an incoming stream of data.
|
21
|
+
#
|
22
|
+
# ThreadedEnumerator provides the enumerations over the individual chunks of data received from the server.
|
23
|
+
#
|
24
|
+
# @example normal iteration over resources.
|
25
|
+
# chunk = threaded_enumerator.next
|
26
|
+
#
|
27
|
+
# @attribute [r] in_q
|
28
|
+
# @return [Queue] Input queue.
|
29
|
+
# @attribute [r] out_q
|
30
|
+
# @return [Queue] Output queue.
|
31
|
+
class ThreadedEnumerator
|
32
|
+
attr_reader :in_q
|
33
|
+
attr_reader :out_q
|
34
|
+
|
35
|
+
# Spawns a new thread and does appropriate clean-up
|
36
|
+
# in case thread fails. Propagates exception back
|
37
|
+
# to main thread.
|
38
|
+
#
|
39
|
+
# @yieldparam in_q[Queue] input queue
|
40
|
+
# @yieldparam out_q[Queue] output queue
|
41
|
+
def initialize
|
42
|
+
@in_q = Queue.new
|
43
|
+
@out_q = Queue.new
|
44
|
+
|
45
|
+
Thread.new do
|
46
|
+
yield @in_q, @out_q
|
47
|
+
rescue StandardError => e
|
48
|
+
@out_q.push e
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def next
|
53
|
+
@in_q.enq :next
|
54
|
+
chunk = @out_q.deq
|
55
|
+
|
56
|
+
if chunk.is_a? StandardError
|
57
|
+
@out_q.close
|
58
|
+
@in_q.close
|
59
|
+
raise chunk
|
60
|
+
end
|
61
|
+
|
62
|
+
if chunk.nil?
|
63
|
+
@out_q.close
|
64
|
+
@in_q.close
|
65
|
+
raise StopIteration
|
66
|
+
end
|
67
|
+
chunk
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/gapic/rest.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gapic-common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Google API Authors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -314,6 +314,8 @@ files:
|
|
314
314
|
- lib/gapic/rest/grpc_transcoder/http_binding.rb
|
315
315
|
- lib/gapic/rest/operation.rb
|
316
316
|
- lib/gapic/rest/paged_enumerable.rb
|
317
|
+
- lib/gapic/rest/server_stream.rb
|
318
|
+
- lib/gapic/rest/threaded_enumerator.rb
|
317
319
|
- lib/gapic/stream_input.rb
|
318
320
|
homepage: https://github.com/googleapis/gapic-generator-ruby
|
319
321
|
licenses:
|