Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Newdigate <andrew@gitlab.com>2017-11-29 12:12:12 +0300
committerRémy Coutable <remy@rymai.me>2017-11-29 12:12:12 +0300
commit64e5f996fa01d2e9c8462cfbb647997531eaf6c7 (patch)
treeb3bebc2fd1be9822f8be2124aee9acff5acd3ded /lib/gitlab/gitaly_client.rb
parenta4f8dddc212fcd91f6a4a09e92b2de6117a21305 (diff)
Add timeouts for Gitaly calls
Diffstat (limited to 'lib/gitlab/gitaly_client.rb')
-rw-r--r--lib/gitlab/gitaly_client.rb43
1 files changed, 39 insertions, 4 deletions
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index d7375938ab6..f27cd800bdd 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -117,11 +117,11 @@ module Gitlab
# kwargs.merge(deadline: Time.now + 10)
# end
#
- def self.call(storage, service, rpc, request, remote_storage: nil)
+ def self.call(storage, service, rpc, request, remote_storage: nil, timeout: nil)
start = Gitlab::Metrics::System.monotonic_time
enforce_gitaly_request_limits(:call)
- kwargs = request_kwargs(storage, remote_storage: remote_storage)
+ kwargs = request_kwargs(storage, timeout, remote_storage: remote_storage)
kwargs = yield(kwargs) if block_given?
stub(service, storage).__send__(rpc, request, kwargs) # rubocop:disable GitlabSecurity/PublicSend
@@ -140,7 +140,7 @@ module Gitlab
end
private_class_method :current_transaction_labels
- def self.request_kwargs(storage, remote_storage: nil)
+ def self.request_kwargs(storage, timeout, remote_storage: nil)
encoded_token = Base64.strict_encode64(token(storage).to_s)
metadata = {
'authorization' => "Bearer #{encoded_token}",
@@ -152,7 +152,22 @@ module Gitlab
metadata['call_site'] = feature.to_s if feature
metadata['gitaly-servers'] = address_metadata(remote_storage) if remote_storage
- { metadata: metadata }
+ result = { metadata: metadata }
+
+ # nil timeout indicates that we should use the default
+ timeout = default_timeout if timeout.nil?
+
+ return result unless timeout > 0
+
+ # Do not use `Time.now` for deadline calculation, since it
+ # will be affected by Timecop in some tests, but grpc's c-core
+ # uses system time instead of timecop's time, so tests will fail
+ # `Time.at(Process.clock_gettime(Process::CLOCK_REALTIME))` will
+ # circumvent timecop
+ deadline = Time.at(Process.clock_gettime(Process::CLOCK_REALTIME)) + timeout
+ result[:deadline] = deadline
+
+ result
end
def self.token(storage)
@@ -325,6 +340,26 @@ module Gitlab
Google::Protobuf::RepeatedField.new(:bytes, a.map { |s| self.encode(s) } )
end
+ # The default timeout on all Gitaly calls
+ def self.default_timeout
+ return 0 if Sidekiq.server?
+
+ timeout(:gitaly_timeout_default)
+ end
+
+ def self.fast_timeout
+ timeout(:gitaly_timeout_fast)
+ end
+
+ def self.medium_timeout
+ timeout(:gitaly_timeout_medium)
+ end
+
+ def self.timeout(timeout_name)
+ Gitlab::CurrentSettings.current_application_settings[timeout_name]
+ end
+ private_class_method :timeout
+
# Count a stack. Used for n+1 detection
def self.count_stack
return unless RequestStore.active?