gapic-common 0.20.0 → 1.2.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,255 @@
1
+ # Copyright 2025 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 "gapic/common/error_codes"
16
+
17
+ module Gapic
18
+ module Common
19
+ ##
20
+ # Gapic Common retry policy base class.
21
+ #
22
+ class RetryPolicy
23
+ # @return [Numeric] Default initial delay in seconds.
24
+ DEFAULT_INITIAL_DELAY = 1
25
+ # @return [Numeric] Default maximum delay in seconds.
26
+ DEFAULT_MAX_DELAY = 15
27
+ # @return [Numeric] Default delay scaling factor for subsequent retry attempts.
28
+ DEFAULT_MULTIPLIER = 1.3
29
+ # @return [Array<String|Integer>] Default list of retry codes.
30
+ DEFAULT_RETRY_CODES = [].freeze
31
+ # @return [Numeric] Default timeout threshold value in seconds.
32
+ DEFAULT_TIMEOUT = 3600 # One hour
33
+
34
+ ##
35
+ # Create new Gapic::Common::RetryPolicy instance.
36
+ #
37
+ # @param initial_delay [Numeric] Initial delay in seconds.
38
+ # @param max_delay [Numeric] Maximum delay in seconds.
39
+ # @param multiplier [Numeric] The delay scaling factor for each subsequent retry attempt.
40
+ # @param retry_codes [Array<String|Integer>] List of retry codes.
41
+ # @param timeout [Numeric] Timeout threshold value in seconds.
42
+ #
43
+ def initialize initial_delay: nil, max_delay: nil, multiplier: nil, retry_codes: nil, timeout: nil
44
+ # Instance values are set as `nil` to determine whether values are overriden from default.
45
+ @initial_delay = initial_delay
46
+ @max_delay = max_delay
47
+ @multiplier = multiplier
48
+ @retry_codes = convert_codes retry_codes
49
+ @timeout = timeout
50
+ start!
51
+ end
52
+
53
+ # @return [Numeric] Initial delay in seconds.
54
+ def initial_delay
55
+ @initial_delay || DEFAULT_INITIAL_DELAY
56
+ end
57
+
58
+ # @return [Numeric] Maximum delay in seconds.
59
+ def max_delay
60
+ @max_delay || DEFAULT_MAX_DELAY
61
+ end
62
+
63
+ # @return [Numeric] The delay scaling factor for each subsequent retry attempt.
64
+ def multiplier
65
+ @multiplier || DEFAULT_MULTIPLIER
66
+ end
67
+
68
+ # @return [Array<Integer>] List of retry codes.
69
+ def retry_codes
70
+ @retry_codes || DEFAULT_RETRY_CODES
71
+ end
72
+
73
+ # @return [Numeric] Timeout threshold value in seconds.
74
+ def timeout
75
+ @timeout || DEFAULT_TIMEOUT
76
+ end
77
+
78
+ ##
79
+ # Returns a duplicate in a non-executing state, i.e. with the deadline
80
+ # and current delay reset.
81
+ #
82
+ # @return [RetryPolicy]
83
+ #
84
+ def dup
85
+ RetryPolicy.new initial_delay: @initial_delay,
86
+ max_delay: @max_delay,
87
+ multiplier: @multiplier,
88
+ retry_codes: @retry_codes,
89
+ timeout: @timeout
90
+ end
91
+
92
+ ##
93
+ # Perform delay if and only if retriable.
94
+ #
95
+ # If positional argument `error` is provided, the retriable logic uses
96
+ # `retry_codes`. Otherwise, `timeout` is used.
97
+ #
98
+ # @return [Boolean] Whether the delay was executed.
99
+ #
100
+ def call error = nil
101
+ should_retry = error.nil? ? retry_with_deadline? : retry_error?(error)
102
+ return false unless should_retry
103
+ perform_delay!
104
+ end
105
+ alias perform_delay call
106
+
107
+ ##
108
+ # Perform delay.
109
+ #
110
+ # @return [Boolean] Whether the delay was executed.
111
+ #
112
+ def perform_delay!
113
+ delay!
114
+ increment_delay!
115
+ @perform_delay_count += 1
116
+ true
117
+ end
118
+
119
+ ##
120
+ # Current delay value in seconds.
121
+ #
122
+ # @return [Numeric] Time delay in seconds.
123
+ #
124
+ def delay
125
+ @delay
126
+ end
127
+
128
+ ##
129
+ # Current number of times the delay has been performed
130
+ #
131
+ # @return [Integer]
132
+ #
133
+ def perform_delay_count
134
+ @perform_delay_count
135
+ end
136
+
137
+ ##
138
+ # Start tracking the deadline and delay by initializing those values.
139
+ #
140
+ # This is normally done when the object is constructed, but it can be
141
+ # done explicitly in order to reinitialize the state in case this
142
+ # retry policy was created in the past or is being reused.
143
+ #
144
+ # @param mock_delay [boolean,Proc] if truthy, delays are "mocked",
145
+ # meaning they do not actually take time, but are measured as if they
146
+ # did, which is useful for tests. If set to a Proc, it will be called
147
+ # whenever a delay would happen, and passed the delay in seconds,
148
+ # also useful for testing.
149
+ #
150
+ def start! mock_delay: false
151
+ @mock_time = mock_delay ? Process.clock_gettime(Process::CLOCK_MONOTONIC) : nil
152
+ @mock_delay_callback = mock_delay.respond_to?(:call) ? mock_delay : nil
153
+ @deadline = cur_time + timeout
154
+ @delay = initial_delay
155
+ @perform_delay_count = 0
156
+ self
157
+ end
158
+
159
+ ##
160
+ # @private
161
+ # @return [Boolean] Whether this error should be retried.
162
+ #
163
+ def retry_error? error
164
+ (defined?(::GRPC) && error.is_a?(::GRPC::BadStatus) && retry_codes.include?(error.code)) ||
165
+ (error.respond_to?(:response_status) &&
166
+ retry_codes.include?(ErrorCodes.grpc_error_for(error.response_status)))
167
+ end
168
+
169
+ # @private
170
+ # @return [Boolean] Whether this policy should be retried based on the deadline.
171
+ def retry_with_deadline?
172
+ deadline > cur_time
173
+ end
174
+
175
+ ##
176
+ # @private
177
+ # Apply default values to the policy object. This does not replace user-provided values,
178
+ # it only overrides empty values.
179
+ #
180
+ # @param retry_policy [Hash] The policy for error retry. Keys must match the arguments for
181
+ # {Gapic::Common::RetryPolicy.new}.
182
+ #
183
+ def apply_defaults retry_policy
184
+ return unless retry_policy.is_a? Hash
185
+ @retry_codes ||= convert_codes retry_policy[:retry_codes]
186
+ @initial_delay ||= retry_policy[:initial_delay]
187
+ @multiplier ||= retry_policy[:multiplier]
188
+ @max_delay ||= retry_policy[:max_delay]
189
+
190
+ self
191
+ end
192
+
193
+ # @private Equality test
194
+ def eql? other
195
+ other.is_a?(RetryPolicy) &&
196
+ other.initial_delay == initial_delay &&
197
+ other.max_delay == max_delay &&
198
+ other.multiplier == multiplier &&
199
+ other.retry_codes == retry_codes &&
200
+ other.timeout == timeout
201
+ end
202
+ alias == eql?
203
+
204
+ # @private Hash code
205
+ def hash
206
+ [initial_delay, max_delay, multiplier, retry_codes, timeout].hash
207
+ end
208
+
209
+ private
210
+
211
+ # @private
212
+ # @return [Numeric] The performed delay.
213
+ def delay!
214
+ if @mock_time
215
+ @mock_time += delay
216
+ @mock_delay_callback&.call delay
217
+ else
218
+ Kernel.sleep delay
219
+ end
220
+ end
221
+
222
+ # @private
223
+ # @return [Numeric] The new delay in seconds.
224
+ def increment_delay!
225
+ @delay = [delay * multiplier, max_delay].min
226
+ end
227
+
228
+ # @private
229
+ # @return [Numeric] The deadline for timeout-based policies.
230
+ def deadline
231
+ @deadline
232
+ end
233
+
234
+ # @private
235
+ # Mockable way to get time.
236
+ def cur_time
237
+ @mock_time || Process.clock_gettime(Process::CLOCK_MONOTONIC)
238
+ end
239
+
240
+ # @private
241
+ # @return [Array<Integer> Error codes converted to their respective integer values.
242
+ def convert_codes input_codes
243
+ return nil if input_codes.nil?
244
+ Array(input_codes).map do |obj|
245
+ case obj
246
+ when String
247
+ ErrorCodes::ERROR_STRING_MAPPING[obj]
248
+ when Integer
249
+ obj
250
+ end
251
+ end.compact
252
+ end
253
+ end
254
+ end
255
+ end
@@ -14,6 +14,6 @@
14
14
 
15
15
  module Gapic
16
16
  module Common
17
- VERSION = "0.20.0".freeze
17
+ VERSION = "1.2.0".freeze
18
18
  end
19
19
  end
data/lib/gapic/common.rb CHANGED
@@ -16,6 +16,7 @@ require "grpc/errors"
16
16
  require "grpc/core/status_codes"
17
17
 
18
18
  require "gapic/common/error"
19
+ require "gapic/common/polling_harness"
19
20
  require "gapic/call_options"
20
21
  require "gapic/headers"
21
22
  require "gapic/operation"
data/lib/gapic/config.rb CHANGED
@@ -50,7 +50,7 @@ module Gapic
50
50
  #
51
51
  def config_attr name, default, *valid_values, &validator
52
52
  name = String(name).to_sym
53
- name_setter = "#{name}=".to_sym
53
+ name_setter = :"#{name}="
54
54
  raise NameError, "invalid config name #{name}" if name !~ /^[a-zA-Z]\w*$/ || name == :parent_config
55
55
  raise NameError, "method #{name} already exists" if method_defined? name
56
56
  raise NameError, "method #{name_setter} already exists" if method_defined? name_setter
@@ -58,7 +58,7 @@ module Gapic
58
58
  raise ArgumentError, "validation must be provided" if validator.nil? && valid_values.empty?
59
59
  validator ||= ->(value) { valid_values.any? { |v| v === value } }
60
60
 
61
- name_ivar = "@#{name}".to_sym
61
+ name_ivar = :"@#{name}"
62
62
 
63
63
  create_getter name_ivar, name, default
64
64
  create_setter name_ivar, name_setter, default, validator
@@ -32,12 +32,13 @@ module Gapic
32
32
  # Creates a new Channel instance
33
33
  #
34
34
  def initialize grpc_stub_class, endpoint:, credentials:, channel_args: nil, interceptors: nil,
35
- on_channel_create: nil
35
+ on_channel_create: nil, stub_logger: nil
36
36
  @grpc_stub_class = grpc_stub_class
37
37
  @endpoint = endpoint
38
38
  @credentials = credentials
39
39
  @channel_args = Hash channel_args
40
40
  @interceptors = Array interceptors
41
+ @stub_logger = stub_logger
41
42
  @concurrent_streams = 0
42
43
  @mutex = Mutex.new
43
44
  setup_grpc_stub
@@ -88,11 +89,10 @@ module Gapic
88
89
  def call_rpc method_name, request, options: nil, &block
89
90
  @mutex.synchronize { @concurrent_streams += 1 }
90
91
  begin
91
- rpc_call = RpcCall.new @grpc_stub.method method_name
92
+ meth = @grpc_stub.method method_name
93
+ rpc_call = RpcCall.new meth, stub_logger: @stub_logger, method_name: method_name
92
94
  response = rpc_call.call request, options: options, &block
93
95
  response
94
- rescue StandardError => e
95
- raise e
96
96
  ensure
97
97
  @mutex.synchronize { @concurrent_streams -= 1 }
98
98
  end
@@ -30,7 +30,12 @@ module Gapic
30
30
  ##
31
31
  # Initialize an instance of ServiceStub::ChannelPool
32
32
  #
33
- def initialize grpc_stub_class, endpoint:, credentials:, channel_args: nil, interceptors: nil, config: nil
33
+ def initialize grpc_stub_class,
34
+ endpoint:, credentials:,
35
+ channel_args: nil,
36
+ interceptors: nil,
37
+ config: nil,
38
+ stub_logger: nil
34
39
  if credentials.is_a? ::GRPC::Core::Channel
35
40
  raise ArgumentError, "Can't create a channel pool with GRPC::Core::Channel as credentials"
36
41
  end
@@ -41,6 +46,7 @@ module Gapic
41
46
  @channel_args = channel_args
42
47
  @interceptors = interceptors
43
48
  @config = config || Configuration.new
49
+ @stub_logger = stub_logger
44
50
 
45
51
  @channels = (1..@config.channel_count).map { create_channel }
46
52
  end
@@ -49,7 +55,8 @@ module Gapic
49
55
  # Creates a new channel.
50
56
  def create_channel
51
57
  Channel.new @grpc_stub_class, endpoint: @endpoint, credentials: @credentials, channel_args: @channel_args,
52
- interceptors: @interceptors, on_channel_create: @config.on_channel_create
58
+ interceptors: @interceptors, on_channel_create: @config.on_channel_create,
59
+ stub_logger: @stub_logger
53
60
  end
54
61
 
55
62
  ##
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require "gapic/call_options"
16
+ require "gapic/logging_concerns"
16
17
  require "grpc/errors"
17
18
 
18
19
  module Gapic
@@ -32,8 +33,11 @@ module Gapic
32
33
  #
33
34
  # @param stub_method [Proc] Used to make a bare rpc call.
34
35
  #
35
- def initialize stub_method
36
+ def initialize stub_method, stub_logger: nil, method_name: nil
36
37
  @stub_method = stub_method
38
+ @stub_logger = stub_logger
39
+ @method_name = method_name
40
+ @request_id = LoggingConcerns.random_uuid4
37
41
  end
38
42
 
39
43
  ##
@@ -44,7 +48,8 @@ module Gapic
44
48
  # customize the options object, using keys that match the arguments for {Gapic::CallOptions.new}. This object
45
49
  # should only be used once.
46
50
  #
47
- # @yield [response, operation] Access the response along with the RPC operation.
51
+ # @yield [response, operation] Access the response along with the RPC operation. Additionally, throwing
52
+ # `:response, obj` within the block will change the return value to `obj`.
48
53
  # @yieldparam response [Object] The response object.
49
54
  # @yieldparam operation [::GRPC::ActiveCall::Operation] The RPC operation for the response.
50
55
  #
@@ -91,7 +96,7 @@ module Gapic
91
96
  # )
92
97
  # response = echo_call.call request, options: options
93
98
  #
94
- # @example Accessing the response and RPC operation using a block:
99
+ # @example Accessing the RPC operation using a block:
95
100
  # require "google/showcase/v1beta1/echo_pb"
96
101
  # require "google/showcase/v1beta1/echo_services_pb"
97
102
  # require "gapic"
@@ -107,8 +112,8 @@ module Gapic
107
112
  # echo_call = Gapic::ServiceStub::RpcCall.new echo_stub.method :echo
108
113
  #
109
114
  # request = Google::Showcase::V1beta1::EchoRequest.new
110
- # echo_call.call request do |response, operation|
111
- # operation.trailing_metadata
115
+ # metadata = echo_call.call request do |_response, operation|
116
+ # throw :response, operation.trailing_metadata
112
117
  # end
113
118
  #
114
119
  def call request, options: nil
@@ -117,21 +122,27 @@ module Gapic
117
122
  deadline = calculate_deadline options
118
123
  metadata = options.metadata
119
124
 
125
+ try_number = 1
120
126
  retried_exception = nil
121
127
  begin
128
+ request = log_request request, metadata, try_number
122
129
  operation = stub_method.call request, deadline: deadline, metadata: metadata, return_op: true
123
130
  response = operation.execute
124
- yield response, operation if block_given?
125
- response
131
+ catch :response do
132
+ response = log_response response, try_number
133
+ yield response, operation if block_given?
134
+ response
135
+ end
126
136
  rescue ::GRPC::DeadlineExceeded => e
137
+ log_response e, try_number
127
138
  raise Gapic::GRPC::DeadlineExceededError.new e.message, root_cause: retried_exception
128
139
  rescue StandardError => e
129
- if e.is_a?(::GRPC::Unavailable) && /Signet::AuthorizationError/ =~ e.message
130
- e = Gapic::GRPC::AuthorizationError.new e.message.gsub(%r{^\d+:}, "")
131
- end
140
+ e = normalize_exception e
141
+ log_response e, try_number
132
142
 
133
143
  if check_retry?(deadline) && options.retry_policy.call(e)
134
144
  retried_exception = e
145
+ try_number += 1
135
146
  retry
136
147
  end
137
148
 
@@ -145,13 +156,110 @@ module Gapic
145
156
  return if options.timeout.nil?
146
157
  return if options.timeout.negative?
147
158
 
148
- Time.now + options.timeout
159
+ current_time + options.timeout
149
160
  end
150
161
 
151
162
  def check_retry? deadline
152
163
  return true if deadline.nil?
153
164
 
154
- deadline > Time.now
165
+ deadline > current_time
166
+ end
167
+
168
+ def current_time
169
+ # An alternative way of saying Time.now without actually calling
170
+ # Time.now. This allows clients that replace Time.now (e.g. via the
171
+ # timecop gem) to do so without interfering with the deadline.
172
+ nanos = Process.clock_gettime Process::CLOCK_REALTIME, :nanosecond
173
+ secs_part = nanos / 1_000_000_000
174
+ nsecs_part = nanos % 1_000_000_000
175
+ Time.at secs_part, nsecs_part, :nanosecond
176
+ end
177
+
178
+ def normalize_exception exception
179
+ if exception.is_a?(::GRPC::Unavailable) && /Signet::AuthorizationError/ =~ exception.message
180
+ exception = Gapic::GRPC::AuthorizationError.new exception.message.gsub(%r{^\d+:}, "")
181
+ end
182
+ exception
183
+ end
184
+
185
+ def log_request request, metadata, try_number
186
+ return request unless @stub_logger&.enabled?
187
+ @stub_logger.info do |entry|
188
+ entry.set_system_name
189
+ entry.set_service
190
+ entry.set "rpcName", @method_name
191
+ entry.set "retryAttempt", try_number
192
+ entry.set "requestId", @request_id
193
+ entry.message =
194
+ if request.is_a? Enumerable
195
+ "Sending stream to #{entry.service}.#{@method_name} (try #{try_number})"
196
+ else
197
+ "Sending request to #{entry.service}.#{@method_name} (try #{try_number})"
198
+ end
199
+ end
200
+ loggable_metadata = metadata.to_h rescue {}
201
+ if request.is_a? Enumerable
202
+ request.lazy.map do |req|
203
+ log_single_request req, loggable_metadata
204
+ end
205
+ else
206
+ log_single_request request, loggable_metadata
207
+ end
208
+ end
209
+
210
+ def log_single_request request, metadata
211
+ request_content = request.respond_to?(:to_h) ? (request.to_h rescue {}) : request.to_s
212
+ if !request_content.empty? || !metadata.empty?
213
+ @stub_logger.debug do |entry|
214
+ entry.set "requestId", @request_id
215
+ entry.set "request", request_content
216
+ entry.set "headers", metadata
217
+ entry.message = "(request payload as #{request.class})"
218
+ end
219
+ end
220
+ request
221
+ end
222
+
223
+ def log_response response, try_number
224
+ return response unless @stub_logger&.enabled?
225
+ @stub_logger.info do |entry|
226
+ entry.set_system_name
227
+ entry.set_service
228
+ entry.set "rpcName", @method_name
229
+ entry.set "retryAttempt", try_number
230
+ entry.set "requestId", @request_id
231
+ case response
232
+ when StandardError
233
+ entry.set "exception", response.to_s
234
+ entry.message = "Received error for #{entry.service}.#{@method_name} (try #{try_number}): #{response}"
235
+ when Enumerable
236
+ entry.message = "Receiving stream for #{entry.service}.#{@method_name} (try #{try_number})"
237
+ else
238
+ entry.message = "Received response for #{entry.service}.#{@method_name} (try #{try_number})"
239
+ end
240
+ end
241
+ case response
242
+ when StandardError
243
+ response
244
+ when Enumerable
245
+ response.lazy.map do |resp|
246
+ log_single_response resp
247
+ end
248
+ else
249
+ log_single_response response
250
+ end
251
+ end
252
+
253
+ def log_single_response response
254
+ response_content = response.respond_to?(:to_h) ? (response.to_h rescue {}) : response.to_s
255
+ unless response_content.empty?
256
+ @stub_logger.debug do |entry|
257
+ entry.set "requestId", @request_id
258
+ entry.set "response", response_content
259
+ entry.message = "(response payload as #{response.class})"
260
+ end
261
+ end
262
+ response
155
263
  end
156
264
  end
157
265
  end
@@ -17,7 +17,8 @@ require "googleauth"
17
17
  require "gapic/grpc/service_stub/rpc_call"
18
18
  require "gapic/grpc/service_stub/channel"
19
19
  require "gapic/grpc/service_stub/channel_pool"
20
-
20
+ require "gapic/logging_concerns"
21
+ require "gapic/universe_domain_concerns"
21
22
 
22
23
  module Gapic
23
24
  ##
@@ -31,6 +32,9 @@ module Gapic
31
32
  # @return [Gapic::ServiceStub::ChannelPool] The instance of the ChannelPool class.
32
33
  #
33
34
  class ServiceStub
35
+ include UniverseDomainConcerns
36
+ include LoggingConcerns
37
+
34
38
  attr_reader :grpc_stub
35
39
  attr_reader :channel_pool
36
40
 
@@ -38,7 +42,12 @@ module Gapic
38
42
  # Creates a Gapic gRPC stub object.
39
43
  #
40
44
  # @param grpc_stub_class [Class] gRPC stub class to create a new instance of.
41
- # @param endpoint [String] The endpoint of the API.
45
+ # @param endpoint [String] The endpoint of the API. Overrides any endpoint_template.
46
+ # @param endpoint_template [String] The endpoint of the API, where the
47
+ # universe domain component of the hostname is marked by the string in
48
+ # the constant {UniverseDomainConcerns::ENDPOINT_SUBSTITUTION}.
49
+ # @param universe_domain [String] The universe domain in which calls should
50
+ # be made. Defaults to `googleapis.com`.
42
51
  # @param credentials [Google::Auth::Credentials, Signet::OAuth2::Client, String, Hash, Proc,
43
52
  # ::GRPC::Core::Channel, ::GRPC::Core::ChannelCredentials] Provides the means for authenticating requests made by
44
53
  # the client. This parameter can be many types:
@@ -57,25 +66,42 @@ module Gapic
57
66
  # be used for intercepting calls before they are executed Interceptors are an EXPERIMENTAL API.
58
67
  # @param channel_pool_config [::Gapic::ServiceStub:ChannelPool::Configuration] The configuration for channel
59
68
  # pool. This argument will raise error when `credentials` is provided as a `::GRPC::Core::Channel`.
60
- #
61
- def initialize grpc_stub_class, endpoint:, credentials:, channel_args: nil,
62
- interceptors: nil, channel_pool_config: nil
69
+ # @param logger [Logger,:default,nil] An explicit logger to use, or one
70
+ # of the values `:default` (the default) to construct a default logger,
71
+ # or `nil` to disable logging explicitly.
72
+ #
73
+ def initialize grpc_stub_class,
74
+ credentials:,
75
+ endpoint: nil,
76
+ endpoint_template: nil,
77
+ universe_domain: nil,
78
+ channel_args: nil,
79
+ interceptors: nil,
80
+ channel_pool_config: nil,
81
+ logger: :default
63
82
  raise ArgumentError, "grpc_stub_class is required" if grpc_stub_class.nil?
64
- raise ArgumentError, "endpoint is required" if endpoint.nil?
65
- raise ArgumentError, "credentials is required" if credentials.nil?
83
+
84
+ setup_universe_domain universe_domain: universe_domain,
85
+ endpoint: endpoint,
86
+ endpoint_template: endpoint_template,
87
+ credentials: credentials
88
+ setup_logging logger: logger,
89
+ system_name: grpc_stub_class,
90
+ service: grpc_stub_class,
91
+ endpoint: self.endpoint,
92
+ client_id: object_id
66
93
 
67
94
  @channel_pool = nil
68
95
  @grpc_stub = nil
69
96
  channel_args = Hash channel_args
70
97
  interceptors = Array interceptors
71
98
 
72
-
73
99
  if channel_pool_config && channel_pool_config.channel_count > 1
74
- create_channel_pool grpc_stub_class, endpoint: endpoint, credentials: credentials,
100
+ create_channel_pool grpc_stub_class, endpoint: self.endpoint, credentials: self.credentials,
75
101
  channel_args: channel_args, interceptors: interceptors,
76
102
  channel_pool_config: channel_pool_config
77
103
  else
78
- create_grpc_stub grpc_stub_class, endpoint: endpoint, credentials: credentials,
104
+ create_grpc_stub grpc_stub_class, endpoint: self.endpoint, credentials: self.credentials,
79
105
  channel_args: channel_args, interceptors: interceptors
80
106
  end
81
107
  end
@@ -87,7 +113,7 @@ module Gapic
87
113
  end
88
114
  @channel_pool = ChannelPool.new grpc_stub_class, endpoint: endpoint, credentials: credentials,
89
115
  channel_args: channel_args, interceptors: interceptors,
90
- config: channel_pool_config
116
+ config: channel_pool_config, stub_logger: stub_logger
91
117
  end
92
118
 
93
119
  def create_grpc_stub grpc_stub_class, endpoint:, credentials:, channel_args: nil, interceptors: nil
@@ -186,7 +212,8 @@ module Gapic
186
212
  #
187
213
  def call_rpc method_name, request, options: nil, &block
188
214
  if @channel_pool.nil?
189
- rpc_call = RpcCall.new @grpc_stub.method method_name
215
+ meth = @grpc_stub.method method_name
216
+ rpc_call = RpcCall.new meth, stub_logger: stub_logger, method_name: method_name
190
217
  rpc_call.call request, options: options, &block
191
218
  else
192
219
  @channel_pool.call_rpc method_name, request, options: options, &block
data/lib/gapic/headers.rb CHANGED
@@ -19,6 +19,8 @@ require "gapic/common/version"
19
19
  module Gapic
20
20
  # A collection of common header values.
21
21
  module Headers
22
+ # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
23
+
22
24
  ##
23
25
  # @param ruby_version [String] The ruby version. Defaults to `RUBY_VERSION`.
24
26
  # @param lib_name [String] The client library name.
@@ -32,10 +34,10 @@ module Gapic
32
34
  # `:grpc` to send the GRPC library version (if defined)
33
35
  # `:rest` to send the REST library version (if defined)
34
36
  # Defaults to `[:grpc]`
37
+ #
35
38
  def self.x_goog_api_client ruby_version: nil, lib_name: nil, lib_version: nil, gax_version: nil,
36
39
  gapic_version: nil, grpc_version: nil, rest_version: nil, protobuf_version: nil,
37
40
  transports_version_send: [:grpc]
38
-
39
41
  ruby_version ||= ::RUBY_VERSION
40
42
  gax_version ||= ::Gapic::Common::VERSION
41
43
  grpc_version ||= ::GRPC::VERSION if defined? ::GRPC::VERSION
@@ -52,4 +54,6 @@ module Gapic
52
54
  x_goog_api_client_header.join " ".freeze
53
55
  end
54
56
  end
57
+
58
+ # rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
55
59
  end