Skip to content

Commit

Permalink
Add a before_fork callback called before forking new molds and new …
Browse files Browse the repository at this point in the history
…workers.

Fix: #76
  • Loading branch information
byroot committed Nov 30, 2023
1 parent 891bc8e commit c35bf33
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 1 deletion.
10 changes: 10 additions & 0 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,16 @@ after_monitor_ready do |server|
end
```

### `before_fork`

Called by the mold before forking a new workers, and by workers before they spawn a new mold.

```ruby
before_fork do |server|
server.logger.info("About to fork, closing connections!")
end
```

### `after_mold_fork`

```ruby
Expand Down
5 changes: 5 additions & 0 deletions lib/pitchfork/configurator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Configurator
:timeout => 22,
:logger => default_logger,
:worker_processes => 1,
:before_fork => nil,
:after_worker_fork => lambda { |server, worker|
server.logger.info("worker=#{worker.nr} gen=#{worker.generation} pid=#{$$} spawned")
},
Expand Down Expand Up @@ -133,6 +134,10 @@ def logger(obj)
set[:logger] = obj
end

def before_fork(*args, &block)
set_hook(:before_fork, block_given? ? block : args[0], 1)
end

def after_worker_fork(*args, &block)
set_hook(:after_worker_fork, block_given? ? block : args[0])
end
Expand Down
5 changes: 4 additions & 1 deletion lib/pitchfork/http_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def extend_deadline(extra_time)

# :stopdoc:
attr_accessor :app, :timeout, :soft_timeout, :cleanup_timeout, :spawn_timeout, :worker_processes,
:after_worker_fork, :after_mold_fork,
:before_fork, :after_worker_fork, :after_mold_fork,
:listener_opts, :children,
:orig_app, :config, :ready_pipe,
:default_middleware, :early_hints
Expand Down Expand Up @@ -563,6 +563,7 @@ def spawn_worker(worker, detach:)
# reason it gets stuck before reaching the worker loop,
# the monitor process will kill it.
worker.update_deadline(@spawn_timeout)
@before_fork&.call(self)
Pitchfork.fork_sibling do
worker.pid = Process.pid

Expand Down Expand Up @@ -870,6 +871,8 @@ def worker_loop(worker)
def spawn_mold(current_generation)
return false unless @promotion_lock.try_lock

@before_fork&.call(self)

begin
Pitchfork.fork_sibling do
mold = Worker.new(nil, pid: Process.pid, generation: current_generation)
Expand Down
16 changes: 16 additions & 0 deletions test/integration/test_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ def test_after_request_complete
assert_clean_shutdown(pid)
end

def test_before_fork
addr, port = unused_port

pid = spawn_server(app: File.join(ROOT, "test/integration/env.ru"), config: <<~CONFIG)
listen "#{addr}:#{port}"
worker_processes 1
before_fork do |server|
$stderr.puts "[before_fork]"
end
CONFIG

assert_healthy("http://#{addr}:#{port}")
assert_stderr("[before_fork]")
assert_clean_shutdown(pid)
end
def test_before_worker_exit
addr, port = unused_port

Expand Down

0 comments on commit c35bf33

Please sign in to comment.