diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-19 18:44:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-19 18:44:42 +0300 |
commit | 4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch) | |
tree | 5423a1c7516cffe36384133ade12572cf709398d /config/initializers | |
parent | e570267f2f6b326480d284e0164a6464ba4081bc (diff) |
Add latest changes from gitlab-org/gitlab@13-12-stable-eev13.12.0-rc42
Diffstat (limited to 'config/initializers')
-rw-r--r-- | config/initializers/01_secret_token.rb | 2 | ||||
-rw-r--r-- | config/initializers/0_inject_enterprise_edition_module.rb | 66 | ||||
-rw-r--r-- | config/initializers/0_license.rb | 2 | ||||
-rw-r--r-- | config/initializers/1_settings.rb | 18 | ||||
-rw-r--r-- | config/initializers/active_record_preloader.rb | 2 | ||||
-rw-r--r-- | config/initializers/active_record_renamed_table.rb | 5 | ||||
-rw-r--r-- | config/initializers/database_config.rb | 14 | ||||
-rw-r--r-- | config/initializers/declarative_policy.rb | 5 | ||||
-rw-r--r-- | config/initializers/geo.rb | 2 | ||||
-rw-r--r-- | config/initializers/gitlab_workhorse_secret.rb | 2 | ||||
-rw-r--r-- | config/initializers/postgres_cte_as_materialized.rb | 2 | ||||
-rw-r--r-- | config/initializers/postgres_partitioning.rb | 2 | ||||
-rw-r--r-- | config/initializers/puma_client_tempfile_patch.rb | 146 | ||||
-rw-r--r-- | config/initializers/request_profiler.rb | 1 | ||||
-rw-r--r-- | config/initializers/rspec_profiling.rb | 2 | ||||
-rw-r--r-- | config/initializers/session_store.rb | 2 | ||||
-rw-r--r-- | config/initializers/stackprof.rb | 135 |
17 files changed, 152 insertions, 256 deletions
diff --git a/config/initializers/01_secret_token.rb b/config/initializers/01_secret_token.rb index c4520b4b313..c1f03dfdb07 100644 --- a/config/initializers/01_secret_token.rb +++ b/config/initializers/01_secret_token.rb @@ -44,7 +44,7 @@ def create_tokens begin File.delete(secret_file) if file_secret_key - rescue => e + rescue StandardError => e warn "Error deleting useless .secret file: #{e}" end end diff --git a/config/initializers/0_inject_enterprise_edition_module.rb b/config/initializers/0_inject_enterprise_edition_module.rb index f9c82f45040..ea3fbda9186 100644 --- a/config/initializers/0_inject_enterprise_edition_module.rb +++ b/config/initializers/0_inject_enterprise_edition_module.rb @@ -3,38 +3,36 @@ require 'active_support/inflector' module InjectEnterpriseEditionModule - def prepend_if_ee(constant, with_descendants: false) - return unless Gitlab.ee? - - prepend_module(constant.constantize, with_descendants) - end - - def extend_if_ee(constant) - extend(constant.constantize) if Gitlab.ee? + def prepend_mod_with(constant_name, namespace: Object, with_descendants: false) + each_extension_for(constant_name, namespace) do |constant| + prepend_module(constant, with_descendants) + end end - def include_if_ee(constant) - include(constant.constantize) if Gitlab.ee? + def extend_mod_with(constant_name, namespace: Object) + each_extension_for( + constant_name, + namespace, + &method(:extend)) end - def prepend_ee_mod(with_descendants: false) - return unless Gitlab.ee? - - prepend_module(ee_module, with_descendants) + def include_mod_with(constant_name, namespace: Object) + each_extension_for( + constant_name, + namespace, + &method(:include)) end - def extend_ee_mod - extend(ee_module) if Gitlab.ee? + def prepend_mod(with_descendants: false) + prepend_mod_with(name, with_descendants: with_descendants) # rubocop: disable Cop/InjectEnterpriseEditionModule end - def include_ee_mod - include(ee_module) if Gitlab.ee? + def extend_mod + extend_mod_with(name) # rubocop: disable Cop/InjectEnterpriseEditionModule end - def prepend_if_jh(constant, with_descendants: false) - return unless Gitlab.jh? - - prepend_module(constant.constantize, with_descendants) + def include_mod + include_mod_with(name) # rubocop: disable Cop/InjectEnterpriseEditionModule end private @@ -47,8 +45,28 @@ module InjectEnterpriseEditionModule end end - def ee_module - ::EE.const_get(name, false) + def each_extension_for(constant_name, namespace) + Gitlab.extensions.each do |extension_name| + extension_namespace = + const_get_maybe_false(namespace, extension_name.upcase) + + extension_module = + const_get_maybe_false(extension_namespace, constant_name) + + yield(extension_module) if extension_module + end + end + + def const_get_maybe_false(mod, name) + # We're still heavily relying on Rails autoloading instead of zeitwerk, + # therefore this check: `mod.const_defined?(name, false)` + # Is not reliable, which may return false while it's defined. + # After we moved everything over to zeitwerk we can avoid rescuing + # NameError and just check if const_defined? + # mod && mod.const_defined?(name, false) && mod.const_get(name, false) + mod && mod.const_get(name, false) + rescue NameError + false end end diff --git a/config/initializers/0_license.rb b/config/initializers/0_license.rb index 3db5ec0a91a..c1a2048b28d 100644 --- a/config/initializers/0_license.rb +++ b/config/initializers/0_license.rb @@ -5,7 +5,7 @@ load_license = lambda do |dir:, license_name:| public_key_file = File.read(Rails.root.join(dir, ".#{prefix}license_encryption_key.pub")) public_key = OpenSSL::PKey::RSA.new(public_key_file) Gitlab::License.encryption_key = public_key -rescue +rescue StandardError warn "WARNING: No valid #{license_name} encryption key provided." end diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 99335321f28..8d5e19afc20 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -564,11 +564,17 @@ Settings.cron_jobs['ssh_keys_expired_notification_worker'] ||= Settingslogic.new Settings.cron_jobs['ssh_keys_expired_notification_worker']['cron'] ||= '0 2 * * *' Settings.cron_jobs['ssh_keys_expired_notification_worker']['job_class'] = 'SshKeys::ExpiredNotificationWorker' Settings.cron_jobs['namespaces_in_product_marketing_emails_worker'] ||= Settingslogic.new({}) -Settings.cron_jobs['namespaces_in_product_marketing_emails_worker']['cron'] ||= '0 9 * * *' +Settings.cron_jobs['namespaces_in_product_marketing_emails_worker']['cron'] ||= '0 16 * * *' Settings.cron_jobs['namespaces_in_product_marketing_emails_worker']['job_class'] = 'Namespaces::InProductMarketingEmailsWorker' Settings.cron_jobs['ssh_keys_expiring_soon_notification_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['ssh_keys_expiring_soon_notification_worker']['cron'] ||= '0 1 * * *' Settings.cron_jobs['ssh_keys_expiring_soon_notification_worker']['job_class'] = 'SshKeys::ExpiringSoonNotificationWorker' +Settings.cron_jobs['users_deactivate_dormant_users_worker'] ||= Settingslogic.new({}) +Settings.cron_jobs['users_deactivate_dormant_users_worker']['cron'] ||= '21,42 0-4 * * *' +Settings.cron_jobs['users_deactivate_dormant_users_worker']['job_class'] = 'Users::DeactivateDormantUsersWorker' +Settings.cron_jobs['ci_delete_unit_tests_worker'] ||= Settingslogic.new({}) +Settings.cron_jobs['ci_delete_unit_tests_worker']['cron'] ||= '0 0 * * *' +Settings.cron_jobs['ci_delete_unit_tests_worker']['job_class'] = 'Ci::DeleteUnitTestsWorker' Gitlab.com do Settings.cron_jobs['batched_background_migrations_worker'] ||= Settingslogic.new({}) @@ -668,7 +674,7 @@ Gitlab.ee do Settings.cron_jobs['elastic_migration_worker']['cron'] ||= '*/30 * * * *' Settings.cron_jobs['elastic_migration_worker']['job_class'] ||= 'Elastic::MigrationWorker' Settings.cron_jobs['sync_seat_link_worker'] ||= Settingslogic.new({}) - Settings.cron_jobs['sync_seat_link_worker']['cron'] ||= "#{rand(60)} 0 * * *" + Settings.cron_jobs['sync_seat_link_worker']['cron'] ||= "#{rand(60)} 3 * * * UTC" Settings.cron_jobs['sync_seat_link_worker']['job_class'] = 'SyncSeatLinkWorker' Settings.cron_jobs['web_application_firewall_metrics_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['web_application_firewall_metrics_worker']['cron'] ||= '0 1 * * 0' @@ -688,6 +694,12 @@ Gitlab.ee do Settings.cron_jobs['vulnerability_historical_statistics_deletion_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['vulnerability_historical_statistics_deletion_worker']['cron'] ||= '15 3 * * *' Settings.cron_jobs['vulnerability_historical_statistics_deletion_worker']['job_class'] = 'Vulnerabilities::HistoricalStatistics::DeletionWorker' + Settings.cron_jobs['security_create_orchestration_policy_worker'] ||= Settingslogic.new({}) + Settings.cron_jobs['security_create_orchestration_policy_worker']['cron'] ||= '*/10 * * * *' + Settings.cron_jobs['security_create_orchestration_policy_worker']['job_class'] = 'Security::CreateOrchestrationPolicyWorker' + Settings.cron_jobs['security_orchestration_policy_rule_schedule_worker'] ||= Settingslogic.new({}) + Settings.cron_jobs['security_orchestration_policy_rule_schedule_worker']['cron'] ||= '*/15 * * * *' + Settings.cron_jobs['security_orchestration_policy_rule_schedule_worker']['job_class'] = 'Security::OrchestrationPolicyRuleScheduleWorker' end # @@ -695,6 +707,7 @@ end # Settings['sidekiq'] ||= Settingslogic.new({}) Settings['sidekiq']['log_format'] ||= 'default' +Settings['sidekiq']['routing_rules'] ||= [] # # GitLab Shell @@ -852,6 +865,7 @@ Settings['extra'] ||= Settingslogic.new({}) Settings.extra['matomo_site_id'] ||= Settings.extra['piwik_site_id'] if Settings.extra['piwik_site_id'].present? Settings.extra['matomo_url'] ||= Settings.extra['piwik_url'] if Settings.extra['piwik_url'].present? Settings.extra['matomo_disable_cookies'] = false if Settings.extra['matomo_disable_cookies'].nil? +Settings.extra['maximum_text_highlight_size_kilobytes'] = Settings.extra.fetch('maximum_text_highlight_size_kilobytes', 512).kilobytes # # Rack::Attack settings diff --git a/config/initializers/active_record_preloader.rb b/config/initializers/active_record_preloader.rb index 257a8a9e955..198c97cb849 100644 --- a/config/initializers/active_record_preloader.rb +++ b/config/initializers/active_record_preloader.rb @@ -4,7 +4,7 @@ module ActiveRecord module Associations class Preloader class NullPreloader - def self.new(klass, owners, reflection, preload_scope) + def self.new(*args, **kwargs) self end diff --git a/config/initializers/active_record_renamed_table.rb b/config/initializers/active_record_renamed_table.rb new file mode 100644 index 00000000000..948ef8790c8 --- /dev/null +++ b/config/initializers/active_record_renamed_table.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +ActiveSupport.on_load(:active_record) do + ActiveRecord::ConnectionAdapters::SchemaCache.prepend(Gitlab::Database::SchemaCacheWithRenamedTable) +end diff --git a/config/initializers/database_config.rb b/config/initializers/database_config.rb index a91f67224d7..6637080c038 100644 --- a/config/initializers/database_config.rb +++ b/config/initializers/database_config.rb @@ -20,25 +20,15 @@ Gitlab.ee do end end -# We configure the database connection pool size automatically based on the -# configured concurrency. We also add some headroom, to make sure we don't run -# out of connections when more threads besides the 'user-facing' ones are -# running. -# -# Read more about this in doc/development/database/client_side_connection_pool.md - -headroom = (ENV["DB_POOL_HEADROOM"].presence || 10).to_i -calculated_pool_size = Gitlab::Runtime.max_threads + headroom - db_config = Gitlab::Database.config || Rails.application.config.database_configuration[Rails.env] -db_config['pool'] = calculated_pool_size +db_config['pool'] = Gitlab::Database.default_pool_size ActiveRecord::Base.establish_connection(db_config) Gitlab.ee do if Gitlab::Runtime.sidekiq? && Gitlab::Geo.geo_database_configured? - Rails.configuration.geo_database['pool'] = calculated_pool_size + Rails.configuration.geo_database['pool'] = Gitlab::Database.default_pool_size Geo::TrackingBase.establish_connection(Rails.configuration.geo_database) end end diff --git a/config/initializers/declarative_policy.rb b/config/initializers/declarative_policy.rb new file mode 100644 index 00000000000..49267584809 --- /dev/null +++ b/config/initializers/declarative_policy.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +DeclarativePolicy.configure do + named_policy :global, ::GlobalPolicy +end diff --git a/config/initializers/geo.rb b/config/initializers/geo.rb index 3278dc9e484..e0530f43899 100644 --- a/config/initializers/geo.rb +++ b/config/initializers/geo.rb @@ -4,6 +4,6 @@ Gitlab.ee do if Gitlab::Geo.connected? && Gitlab::Geo.primary? Gitlab::Geo.current_node&.update_clone_url! end -rescue => e +rescue StandardError => e warn "WARNING: Unable to check/update clone_url_prefix for Geo: #{e}" end diff --git a/config/initializers/gitlab_workhorse_secret.rb b/config/initializers/gitlab_workhorse_secret.rb index 5c959a72bd1..88fabe50e83 100644 --- a/config/initializers/gitlab_workhorse_secret.rb +++ b/config/initializers/gitlab_workhorse_secret.rb @@ -2,7 +2,7 @@ begin Gitlab::Workhorse.secret -rescue +rescue StandardError Gitlab::Workhorse.write_secret end diff --git a/config/initializers/postgres_cte_as_materialized.rb b/config/initializers/postgres_cte_as_materialized.rb index 85b3361e25e..fd6e7b48c25 100644 --- a/config/initializers/postgres_cte_as_materialized.rb +++ b/config/initializers/postgres_cte_as_materialized.rb @@ -6,7 +6,7 @@ module Arel class Arel::Visitors::PostgreSQL def visit_Gitlab_Database_AsWithMaterialized(obj, collector) # rubocop:disable Naming/MethodName collector = visit obj.left, collector - collector << " AS#{obj.expr} " + collector << " AS " visit obj.right, collector end end diff --git a/config/initializers/postgres_partitioning.rb b/config/initializers/postgres_partitioning.rb index 6b64ea3f83d..787e46c2405 100644 --- a/config/initializers/postgres_partitioning.rb +++ b/config/initializers/postgres_partitioning.rb @@ -4,7 +4,7 @@ # (even with eager loading disabled). Gitlab::Database::Partitioning::PartitionCreator.register(AuditEvent) -Gitlab::Database::Partitioning::PartitionCreator.register(WebHookLogPartitioned) +Gitlab::Database::Partitioning::PartitionCreator.register(WebHookLog) begin Gitlab::Database::Partitioning::PartitionCreator.new.create_partitions unless ENV['DISABLE_POSTGRES_PARTITION_CREATION_ON_STARTUP'] diff --git a/config/initializers/puma_client_tempfile_patch.rb b/config/initializers/puma_client_tempfile_patch.rb index e1faa21804f..972eeaf0c83 100644 --- a/config/initializers/puma_client_tempfile_patch.rb +++ b/config/initializers/puma_client_tempfile_patch.rb @@ -1,101 +1,99 @@ # frozen_string_literal: true if Gitlab::Runtime.puma? + # This patch represents https://github.com/puma/puma/pull/2613. If + # this PR is accepted in the next Puma release, we can remove this + # entire file. + # + # The patch itself is quite large because the tempfile creation in + # Puma is inside these fairly long methods. The actual changes are + # just two lines, commented with 'GitLab' to make them easier to find. raise "Remove this monkey patch: #{__FILE__}" unless Puma::Const::VERSION == '5.1.1' - if ENV['GITLAB_TEMPFILE_IMMEDIATE_UNLINK'] == '1' - # This is copied from https://github.com/puma/puma/blob/v5.1.1/lib/puma/client.rb, - # with two additions: both times we create a temporary file, we immediately - # call `#unlink`. This means that if the process gets terminated without being - # able to clean up itself, the temporary file will not linger on the file - # system. We will try to get this patch accepted upstream if it works for us - # (we just need to check if the temporary file responds to `#unlink` as that - # won't work on Windows, for instance). - module Puma - class Client - private - - def setup_body - @body_read_start = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) - - if @env[HTTP_EXPECT] == CONTINUE - # TODO allow a hook here to check the headers before - # going forward - @io << HTTP_11_100 - @io.flush - end + module Puma + class Client + private + + def setup_body + @body_read_start = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) - @read_header = false + if @env[HTTP_EXPECT] == CONTINUE + # TODO allow a hook here to check the headers before + # going forward + @io << HTTP_11_100 + @io.flush + end - body = @parser.body + @read_header = false - te = @env[TRANSFER_ENCODING2] + body = @parser.body - if te - if te.include?(",") - te.split(",").each do |part| - if CHUNKED.casecmp(part.strip) == 0 # rubocop:disable Metrics/BlockNesting - return setup_chunked_body(body) - end + te = @env[TRANSFER_ENCODING2] + + if te + if te.include?(",") + te.split(",").each do |part| + if CHUNKED.casecmp(part.strip) == 0 # rubocop:disable Metrics/BlockNesting + return setup_chunked_body(body) end - elsif CHUNKED.casecmp(te) == 0 - return setup_chunked_body(body) end + elsif CHUNKED.casecmp(te) == 0 + return setup_chunked_body(body) end + end - @chunked_body = false + @chunked_body = false - cl = @env[CONTENT_LENGTH] + cl = @env[CONTENT_LENGTH] - unless cl - @buffer = body.empty? ? nil : body - @body = EmptyBody - set_ready - return true - end + unless cl + @buffer = body.empty? ? nil : body + @body = EmptyBody + set_ready + return true + end - remain = cl.to_i - body.bytesize + remain = cl.to_i - body.bytesize - if remain <= 0 - @body = StringIO.new(body) - @buffer = nil - set_ready - return true - end + if remain <= 0 + @body = StringIO.new(body) + @buffer = nil + set_ready + return true + end - if remain > MAX_BODY - @body = Tempfile.new(Const::PUMA_TMP_BASE) - @body.binmode - @body.unlink # This is the changed part - @tempfile = @body - else - # The body[0,0] trick is to get an empty string in the same - # encoding as body. - @body = StringIO.new body[0,0] # rubocop:disable Layout/SpaceAfterComma - end + if remain > MAX_BODY + @body = Tempfile.new(Const::PUMA_TMP_BASE) + @body.binmode + @body.unlink # GitLab: this is the changed part + @tempfile = @body + else + # The body[0,0] trick is to get an empty string in the same + # encoding as body. + @body = StringIO.new body[0,0] # rubocop:disable Layout/SpaceAfterComma + end - @body.write body + @body.write body - @body_remain = remain + @body_remain = remain - return false # rubocop:disable Style/RedundantReturn - end + return false # rubocop:disable Style/RedundantReturn + end - def setup_chunked_body(body) - @chunked_body = true - @partial_part_left = 0 - @prev_chunk = "" + def setup_chunked_body(body) + @chunked_body = true + @partial_part_left = 0 + @prev_chunk = "" - @body = Tempfile.new(Const::PUMA_TMP_BASE) - @body.binmode - @body.unlink # This is the changed part - @tempfile = @body - @chunked_content_length = 0 + @body = Tempfile.new(Const::PUMA_TMP_BASE) + @body.binmode + @body.unlink # GitLab: this is the changed part + @tempfile = @body + @chunked_content_length = 0 - if decode_chunk(body) - @env[CONTENT_LENGTH] = @chunked_content_length - return true # rubocop:disable Style/RedundantReturn - end + if decode_chunk(body) + @env[CONTENT_LENGTH] = @chunked_content_length + return true # rubocop:disable Style/RedundantReturn end end end diff --git a/config/initializers/request_profiler.rb b/config/initializers/request_profiler.rb index 8e426772b9a..2eb9f53d2a3 100644 --- a/config/initializers/request_profiler.rb +++ b/config/initializers/request_profiler.rb @@ -2,4 +2,5 @@ Rails.application.configure do |config| config.middleware.use(Gitlab::RequestProfiler::Middleware) + config.middleware.use(Gitlab::Middleware::Speedscope) end diff --git a/config/initializers/rspec_profiling.rb b/config/initializers/rspec_profiling.rb index 2473dc1ff6c..1288fad8a94 100644 --- a/config/initializers/rspec_profiling.rb +++ b/config/initializers/rspec_profiling.rb @@ -43,7 +43,7 @@ module RspecProfilingExt module Run def example_finished(*args) super - rescue => err + rescue StandardError => err return if @already_logged_example_finished_error # rubocop:disable Gitlab/ModuleWithInstanceVariables warn "rspec_profiling couldn't collect an example: #{err}. Further warnings suppressed." diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index 6e0cd33aa96..530d7342d57 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -7,7 +7,7 @@ require 'gitlab/current_settings' # allow it to fail: it may do so when create_from_defaults is executed before migrations are actually done begin Settings.gitlab['session_expire_delay'] = Gitlab::CurrentSettings.current_application_settings.session_expire_delay || 10080 -rescue +rescue StandardError Settings.gitlab['session_expire_delay'] ||= 10080 end diff --git a/config/initializers/stackprof.rb b/config/initializers/stackprof.rb index 4c4d241f065..4ff219cfda1 100644 --- a/config/initializers/stackprof.rb +++ b/config/initializers/stackprof.rb @@ -1,140 +1,5 @@ # frozen_string_literal: true -# trigger stackprof by sending a SIGUSR2 signal -# -# Docs: https://docs.gitlab.com/ee/development/performance.html#production - -module Gitlab - class StackProf - DEFAULT_FILE_PREFIX = Dir.tmpdir - DEFAULT_TIMEOUT_SEC = 30 - DEFAULT_MODE = :cpu - # Sample interval as a frequency in microseconds (~100hz); appropriate for CPU profiles - DEFAULT_INTERVAL_US = 10_000 - # Sample interval in event occurrences (n = every nth event); appropriate for allocation profiles - DEFAULT_INTERVAL_EVENTS = 1_000 - - # this is a workaround for sidekiq, which defines its own SIGUSR2 handler. - # by defering to the sidekiq startup event, we get to set up our own - # handler late enough. - # see also: https://github.com/mperham/sidekiq/pull/4653 - def self.install - require 'stackprof' - require 'tmpdir' - - if Gitlab::Runtime.sidekiq? - Sidekiq.configure_server do |config| - config.on :startup do - on_worker_start - end - end - else - Gitlab::Cluster::LifecycleEvents.on_worker_start do - on_worker_start - end - end - end - - def self.on_worker_start - log_event('listening for SIGUSR2 signal') - - # create a pipe in order to propagate signal out of the signal handler - # see also: https://cr.yp.to/docs/selfpipe.html - read, write = IO.pipe - - # create a separate thread that polls for signals on the pipe. - # - # this way we do not execute in signal handler context, which - # lifts restrictions and also serializes the calls in a thread-safe - # manner. - # - # it's very similar to a goroutine and channel design. - # - # another nice benefit of this method is that we can timeout the - # IO.select call, allowing the profile to automatically stop after - # a given interval (by default 30 seconds), avoiding unbounded memory - # growth from a profile that was started and never stopped. - t = Thread.new do - timeout_s = ENV['STACKPROF_TIMEOUT_S']&.to_i || DEFAULT_TIMEOUT_SEC - current_timeout_s = nil - loop do - read.getbyte if IO.select([read], nil, nil, current_timeout_s) - - if ::StackProf.running? - stackprof_file_prefix = ENV['STACKPROF_FILE_PREFIX'] || DEFAULT_FILE_PREFIX - stackprof_out_file = "#{stackprof_file_prefix}/stackprof.#{Process.pid}.#{SecureRandom.hex(6)}.profile" - - log_event( - 'stopping profile', - profile_filename: stackprof_out_file, - profile_timeout_s: timeout_s - ) - - ::StackProf.stop - ::StackProf.results(stackprof_out_file) - current_timeout_s = nil - else - mode = ENV['STACKPROF_MODE']&.to_sym || DEFAULT_MODE - interval = ENV['STACKPROF_INTERVAL']&.to_i - interval ||= (mode == :object ? DEFAULT_INTERVAL_EVENTS : DEFAULT_INTERVAL_US) - - log_event( - 'starting profile', - profile_mode: mode, - profile_interval: interval, - profile_timeout: timeout_s - ) - - ::StackProf.start( - mode: mode, - raw: Gitlab::Utils.to_boolean(ENV['STACKPROF_RAW'] || 'true'), - interval: interval - ) - current_timeout_s = timeout_s - end - end - rescue => e - log_event("stackprof failed: #{e}") - end - t.abort_on_exception = true - - # in the case of puma, this will override the existing SIGUSR2 signal handler - # that can be used to trigger a restart. - # - # puma cluster has two types of restarts: - # * SIGUSR1: phased restart - # * SIGUSR2: restart - # - # phased restart is not supported in our configuration, because we use - # preload_app. this means we will always perform a normal restart. - # additionally, phased restart is not supported when sending a SIGUSR2 - # directly to a puma worker (as opposed to the master process). - # - # the result is that the behaviour of SIGUSR1 and SIGUSR2 is identical in - # our configuration, and we can always use a SIGUSR1 to perform a restart. - # - # thus, it is acceptable for us to re-appropriate the SIGUSR2 signal, and - # override the puma behaviour. - # - # see also: - # * https://github.com/puma/puma/blob/master/docs/signals.md#puma-signals - # * https://github.com/phusion/unicorn/blob/master/SIGNALS - # * https://github.com/mperham/sidekiq/wiki/Signals - Signal.trap('SIGUSR2') do - write.write('.') - end - end - - def self.log_event(event, labels = {}) - Gitlab::AppJsonLogger.info({ - event: 'stackprof', - message: event, - pid: Process.pid - }.merge(labels.compact)) - end - end -end - if Gitlab::Utils.to_boolean(ENV['STACKPROF_ENABLED'].to_s) Gitlab::StackProf.install end |