summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-22 00:06:05 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-22 00:06:05 +0000
commit8dfb94309c3e84937189f73a4149d654e20332e9 (patch)
tree1543a7b74b2e5c683a39fd93b09afc578f758c2b /app
parent170f0bdcdef9c9b226abfe0a50d6687c65e8d613 (diff)
downloadgitlab-ce-8dfb94309c3e84937189f73a4149d654e20332e9.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue8
-rw-r--r--app/controllers/projects/merge_requests_controller.rb2
-rw-r--r--app/helpers/environments_helper.rb1
-rw-r--r--app/models/environment.rb4
-rw-r--r--app/models/merge_request.rb32
5 files changed, 42 insertions, 5 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
index 339e154affc..57be97855e3 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
@@ -65,9 +65,13 @@ export default {
simplePoll(this.checkRebaseStatus);
})
.catch(error => {
- this.rebasingError = error.merge_error;
this.isMakingRequest = false;
- Flash(__('Something went wrong. Please try again.'));
+
+ if (error.response && error.response.data && error.response.data.merge_error) {
+ this.rebasingError = error.response.data.merge_error;
+ } else {
+ Flash(__('Something went wrong. Please try again.'));
+ }
});
},
checkRebaseStatus(continuePolling, stopPolling) {
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index e6032323c13..8d388151dbc 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -226,6 +226,8 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
@merge_request.rebase_async(current_user.id)
head :ok
+ rescue MergeRequest::RebaseLockTimeout => e
+ render json: { merge_error: e.message }, status: :conflict
end
def discussions
diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb
index c642a64ad61..f57d0fa19d4 100644
--- a/app/helpers/environments_helper.rb
+++ b/app/helpers/environments_helper.rb
@@ -34,6 +34,7 @@ module EnvironmentsHelper
"project-path" => project_path(project),
"tags-path" => project_tags_path(project),
"has-metrics" => "#{environment.has_metrics?}",
+ "prometheus-status" => "#{environment.prometheus_status}",
"external-dashboard-url" => project.metrics_setting_external_dashboard_url
}
end
diff --git a/app/models/environment.rb b/app/models/environment.rb
index af0c219d9a0..b426941d8af 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -188,6 +188,10 @@ class Environment < ApplicationRecord
prometheus_adapter.query(:environment, self) if has_metrics?
end
+ def prometheus_status
+ deployment_platform&.cluster&.application_prometheus&.status_name
+ end
+
def additional_metrics(*args)
return unless has_metrics?
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 6ef84c5f59b..b1c7e778743 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -220,6 +220,10 @@ class MergeRequest < ApplicationRecord
alias_attribute :auto_merge_enabled, :merge_when_pipeline_succeeds
alias_method :issuing_parent, :target_project
+ RebaseLockTimeout = Class.new(StandardError)
+
+ REBASE_LOCK_MESSAGE = _("Failed to enqueue the rebase operation, possibly due to a long-lived transaction. Try again later.")
+
def self.reference_prefix
'!'
end
@@ -409,9 +413,7 @@ class MergeRequest < ApplicationRecord
# Set off a rebase asynchronously, atomically updating the `rebase_jid` of
# the MR so that the status of the operation can be tracked.
def rebase_async(user_id)
- transaction do
- lock!
-
+ with_rebase_lock do
raise ActiveRecord::StaleObjectError if !open? || rebase_in_progress?
# Although there is a race between setting rebase_jid here and clearing it
@@ -1468,6 +1470,30 @@ class MergeRequest < ApplicationRecord
private
+ def with_rebase_lock
+ if Feature.enabled?(:merge_request_rebase_nowait_lock, default_enabled: true)
+ with_retried_nowait_lock { yield }
+ else
+ with_lock(true) { yield }
+ end
+ end
+
+ # If the merge request is idle in transaction or has a SELECT FOR
+ # UPDATE, we don't want to block indefinitely or this could cause a
+ # queue of SELECT FOR UPDATE calls. Instead, try to get the lock for
+ # 5 s before raising an error to the user.
+ def with_retried_nowait_lock
+ # Try at most 0.25 + (1.5 * .25) + (1.5^2 * .25) ... (1.5^5 * .25) = 5.2 s to get the lock
+ Retriable.retriable(on: ActiveRecord::LockWaitTimeout, tries: 6, base_interval: 0.25) do
+ with_lock('FOR UPDATE NOWAIT') do
+ yield
+ end
+ end
+ rescue ActiveRecord::LockWaitTimeout => e
+ Gitlab::Sentry.track_acceptable_exception(e)
+ raise RebaseLockTimeout, REBASE_LOCK_MESSAGE
+ end
+
def source_project_variables
Gitlab::Ci::Variables::Collection.new.tap do |variables|
break variables unless source_project