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

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Vosmaer <jacob@gitlab.com>2019-10-08 19:18:04 +0300
committerJacob Vosmaer <jacob@gitlab.com>2019-10-08 19:18:04 +0300
commit566c5e8b59f854c4d4c0f0ee2b42e480fbb18b6d (patch)
tree230960dda6446d26904081b84b5e6ba7eed9c6e9
parentef20063319087df84880c53a03a8761c12b5ea9a (diff)
Add pre-forking benchmarkjv-explore-ruby-fork
-rw-r--r--benchmark-fork.rb84
1 files changed, 75 insertions, 9 deletions
diff --git a/benchmark-fork.rb b/benchmark-fork.rb
index 61078ca3f..f90c9a2d1 100644
--- a/benchmark-fork.rb
+++ b/benchmark-fork.rb
@@ -5,10 +5,11 @@ require 'fileutils'
DEPS = %w[rugged linguist]
N = 100
FORK_SOCKET = 'fork.socket'
+PRE_FORK_SOCKET = 'pre-fork.socket'
THREAD_SOCKET = 'thread.socket'
OID_REGEX = /^[a-f0-9]{40}$/
-class ForkServer
+class ForkServer < Struct.new(:socket_path)
def run
DEPS.each { |dep| require(dep) }
@@ -22,8 +23,8 @@ class ForkServer
end
end
- FileUtils.rm_f(FORK_SOCKET)
- l = Socket.unix_server_socket(FORK_SOCKET)
+ FileUtils.rm_f(socket_path)
+ l = Socket.unix_server_socket(socket_path)
loop do
conn, _addrinfo = l.accept
@@ -39,12 +40,12 @@ class ForkServer
end
end
-class ThreadServer
+class ThreadServer < Struct.new(:socket_path)
def run
DEPS.each { |dep| require(dep) }
- FileUtils.rm_f(THREAD_SOCKET)
- l = Socket.unix_server_socket(THREAD_SOCKET)
+ FileUtils.rm_f(socket_path)
+ l = Socket.unix_server_socket(socket_path)
loop do
conn, _addrinfo = l.accept
@@ -59,18 +60,70 @@ class ThreadServer
end
end
+class PreForkServer < Struct.new(:socket_path)
+ WORKERS = 2
+ REUSE = 10
+
+ def run
+ DEPS.each { |dep| require(dep) }
+
+ FileUtils.rm_f(socket_path)
+ listener = Socket.unix_server_socket(socket_path)
+
+ WORKERS.times.map { fork { handle(listener, Process.pid) } }
+
+ loop do
+ Process.wait
+ fork { handle(listener, Process.pid) }
+ end
+ end
+
+ def handle(listener, ppid)
+ can_exit = false
+ mu = Mutex.new
+
+ Thread.new do
+ loop do
+ sleep 1
+
+ begin
+ Process.kill(0, ppid)
+ rescue
+ mu.synchronize { exit if can_exit }
+ end
+ end
+ end
+
+
+ REUSE.times do
+ mu.synchronize { can_exit = true }
+ conn, _addrinfo = listener.accept
+ mu.synchronize { can_exit = false }
+
+ repo = Rugged::Repository.new('.')
+ conn.write(repo.head.target.oid)
+ conn.close
+ end
+ end
+end
+
def main
pids = [
- fork { ForkServer.new.run },
- fork { ThreadServer.new.run }
+ fork { ForkServer.new(FORK_SOCKET).run },
+ fork { ThreadServer.new(THREAD_SOCKET).run },
+ fork { PreForkServer.new(PRE_FORK_SOCKET).run },
]
+ [FORK_SOCKET, THREAD_SOCKET, PRE_FORK_SOCKET].each do |sock|
+ try_connect(sock)
+ end
Benchmark.bm(15) do |x|
n_spawn = N / 10
- x.report("spawn (#{n_spawn}):") { n_spawn.times { benchmark_spawn } }
+ x.report("pre-fork (#{N}):") { N.times { benchmark_socket(PRE_FORK_SOCKET) } }
x.report("fork (#{N}):") { N.times { benchmark_socket(FORK_SOCKET) } }
x.report("thread (#{N}):") { N.times { benchmark_socket(THREAD_SOCKET) } }
+ x.report("spawn (#{n_spawn}):") { n_spawn.times { benchmark_spawn } }
end
ensure
@@ -95,4 +148,17 @@ def benchmark_socket(socket)
end
end
+def try_connect(sock)
+ 500.times do
+ begin
+ UNIXSocket.new(sock).read
+ return
+ rescue Errno::ENOENT, Errno::ECONNREFUSED
+ sleep 0.1
+ end
+ end
+
+ UNIXSocket.new(sock).read
+end
+
main