Skip to content
代码片段 群组 项目
提交 1113831c 编辑于 作者: Matthias Kaeppler's avatar Matthias Kaeppler
浏览文件

Add lifecycle hook for worker stop event

This will be used soon in order to produce
heap dumps when a worker was terminated due
to high memory use.
上级 cbd155f7
No related branches found
No related tags found
无相关合并请求
...@@ -83,6 +83,10 @@ def enable_semi_reliable_fetch_mode? ...@@ -83,6 +83,10 @@ def enable_semi_reliable_fetch_mode?
end end
end end
config.on(:shutdown) do
Gitlab::Cluster::LifecycleEvents.do_worker_stop
end
if enable_reliable_fetch? if enable_reliable_fetch?
config.options[:semi_reliable_fetch] = enable_semi_reliable_fetch_mode? config.options[:semi_reliable_fetch] = enable_semi_reliable_fetch_mode?
Sidekiq::ReliableFetch.setup_reliable_fetch!(config) Sidekiq::ReliableFetch.setup_reliable_fetch!(config)
......
...@@ -67,6 +67,11 @@ ...@@ -67,6 +67,11 @@
Gitlab::Cluster::LifecycleEvents.do_worker_start Gitlab::Cluster::LifecycleEvents.do_worker_start
end end
on_worker_shutdown do
# Signal application hooks that a worker is shutting down
Gitlab::Cluster::LifecycleEvents.do_worker_stop
end
# Preload the application before starting the workers; this conflicts with # Preload the application before starting the workers; this conflicts with
# phased restart feature. (off by default) # phased restart feature. (off by default)
......
...@@ -57,6 +57,11 @@ on_worker_boot do ...@@ -57,6 +57,11 @@ on_worker_boot do
Gitlab::Cluster::LifecycleEvents.do_worker_start Gitlab::Cluster::LifecycleEvents.do_worker_start
end end
on_worker_shutdown do
# Signal application hooks that a worker is shutting down
Gitlab::Cluster::LifecycleEvents.do_worker_stop
end
# Preload the application before starting the workers; this conflicts with # Preload the application before starting the workers; this conflicts with
# phased restart feature. (off by default) # phased restart feature. (off by default)
preload_app! preload_app!
......
...@@ -63,6 +63,15 @@ module Cluster ...@@ -63,6 +63,15 @@ module Cluster
# #
# Sidekiq/Puma Single: This is called immediately. # Sidekiq/Puma Single: This is called immediately.
# #
# - on_worker_stop (on worker process):
#
# Puma Cluster: Called in the worker process
# exactly once after it stops processing requests
# but before it shuts down.
#
# Sidekiq: Called after the scheduler shuts down but
# before the worker finishes ongoing jobs.
#
# Blocks will be executed in the order in which they are registered. # Blocks will be executed in the order in which they are registered.
# #
class LifecycleEvents class LifecycleEvents
...@@ -113,6 +122,10 @@ def on_master_start(&block) ...@@ -113,6 +122,10 @@ def on_master_start(&block)
end end
end end
def on_worker_stop(&block)
(@worker_stop_hooks ||= []) << block
end
# #
# Lifecycle integration methods (called from puma.rb, etc.) # Lifecycle integration methods (called from puma.rb, etc.)
# #
...@@ -137,6 +150,10 @@ def do_before_master_restart ...@@ -137,6 +150,10 @@ def do_before_master_restart
call(:master_restart_hooks, @master_restart_hooks) call(:master_restart_hooks, @master_restart_hooks)
end end
def do_worker_stop
call(:worker_stop_hooks, @worker_stop_hooks)
end
# DEPRECATED # DEPRECATED
alias_method :do_master_restart, :do_before_master_restart alias_method :do_master_restart, :do_before_master_restart
......
...@@ -3,38 +3,55 @@ ...@@ -3,38 +3,55 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Gitlab::Cluster::LifecycleEvents do RSpec.describe Gitlab::Cluster::LifecycleEvents do
using RSpec::Parameterized::TableSyntax
# we create a new instance to ensure that we do not touch existing hooks # we create a new instance to ensure that we do not touch existing hooks
let(:replica) { Class.new(described_class) } let(:replica) { Class.new(described_class) }
context 'hooks execution' do before do
using RSpec::Parameterized::TableSyntax # disable blackout period to speed-up tests
stub_config(shutdown: { blackout_seconds: 0 })
end
where(:method, :hook_names) do context 'outside of clustered environments' do
:do_worker_start | %i[worker_start_hooks] where(:hook, :was_executed_immediately) do
:do_before_fork | %i[before_fork_hooks] :on_worker_start | true
:do_before_graceful_shutdown | %i[master_blackout_period master_graceful_shutdown] :on_before_fork | false
:do_before_master_restart | %i[master_restart_hooks] :on_before_graceful_shutdown | false
:on_before_master_restart | false
:on_worker_stop | false
end end
before do with_them do
# disable blackout period to speed-up tests it 'executes the given block immediately' do
stub_config(shutdown: { blackout_seconds: 0 }) was_executed = false
replica.public_send(hook, &proc { was_executed = true })
expect(was_executed).to eq(was_executed_immediately)
end
end end
end
with_them do context 'in clustered environments' do
subject { replica.public_send(method) } before do
allow(Gitlab::Runtime).to receive(:puma?).and_return(true)
replica.set_puma_options(workers: 2)
end
it 'executes all hooks' do where(:hook, :execution_helper) do
hook_names.each do |hook_name| :on_worker_start | :do_worker_start
hook = double :on_before_fork | :do_before_fork
replica.instance_variable_set(:"@#{hook_name}", [hook]) :on_before_graceful_shutdown | :do_before_graceful_shutdown
:on_before_master_restart | :do_before_master_restart
:on_worker_stop | :do_worker_stop
end
# ensure that proper hooks are called with_them do
expect(hook).to receive(:call) it 'requires explicit execution via do_* helper' do
expect(replica).to receive(:call).with(hook_name, anything).and_call_original was_executed = false
end replica.public_send(hook, &proc { was_executed = true })
subject expect { replica.public_send(execution_helper) }.to change { was_executed }.from(false).to(true)
end end
end end
end end
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册