Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
4b34720c
Commit
4b34720c
authored
Aug 03, 2017
by
Bob Van Landuyt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use ruby's `File.stat` to check storage availability
parent
3a2aaed8
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
27 additions
and
22 deletions
+27
-22
lib/gitlab/git/storage/forked_storage_check.rb
lib/gitlab/git/storage/forked_storage_check.rb
+15
-19
spec/lib/gitlab/git/storage/forked_storage_check_spec.rb
spec/lib/gitlab/git/storage/forked_storage_check_spec.rb
+12
-3
No files found.
lib/gitlab/git/storage/forked_storage_check.rb
View file @
4b34720c
...
@@ -11,7 +11,7 @@ module Gitlab
...
@@ -11,7 +11,7 @@ module Gitlab
end
end
def
timeout_check
(
path
,
timeout_seconds
)
def
timeout_check
(
path
,
timeout_seconds
)
filesystem_check_pid
=
check_filesystem_in_
fork
(
path
)
filesystem_check_pid
=
check_filesystem_in_
process
(
path
)
deadline
=
timeout_seconds
.
seconds
.
from_now
.
utc
deadline
=
timeout_seconds
.
seconds
.
from_now
.
utc
wait_time
=
0.01
wait_time
=
0.01
...
@@ -31,27 +31,23 @@ module Gitlab
...
@@ -31,27 +31,23 @@ module Gitlab
status
status
end
end
# This call forks out into a process, that process will then be replaced
# This will spawn a new 2 processes to do the check:
# With an `exec` call, since we fork out into a shell, we can create a
# The outer child (waiter) will spawn another child process (stater).
# child process without needing an ActiveRecord-connection.
#
#
# Inside the shell, we use `& wait` to fork another child. We do this
# The stater is the process is performing the actual filesystem check
# to prevent leaving a zombie process when the parent gets killed by the
# the check might hang if the filesystem is acting up.
# timeout.
# In this case we will send a `KILL` to the waiter, which will still
#
# be responsive while the stater is hanging.
# https://stackoverflow.com/questions/27892975/what-causes-activerecord-breaking-postgres-connection-after-forking
def
check_filesystem_in_process
(
path
)
# https://stackoverflow.com/questions/22012943/activerecordstatementinvalid-runtimeerror-the-connection-cannot-be-reused-in
spawn
(
'ruby'
,
'-e'
,
ruby_check
,
path
,
[
:out
,
:err
]
=>
'/dev/null'
)
def
check_filesystem_in_fork
(
path
)
fork
do
STDOUT
.
reopen
(
'/dev/null'
)
STDERR
.
reopen
(
'/dev/null'
)
exec
(
"(
#{
test_script
(
path
)
}
) & wait %1"
)
end
end
end
def
test_script
(
path
)
def
ruby_check
"testpath=$(realpath
#{
Shellwords
.
escape
(
path
)
}
) && stat
\"
$testpath
\"
"
<<~
RUBY_FILESYSTEM_CHECK
inner_pid = fork { File.stat(ARGV.first) }
Process.waitpid(inner_pid)
exit $?.exitstatus
RUBY_FILESYSTEM_CHECK
end
end
end
end
end
end
...
...
spec/lib/gitlab/git/storage/forked_storage_check_spec.rb
View file @
4b34720c
...
@@ -17,11 +17,20 @@ describe Gitlab::Git::Storage::ForkedStorageCheck, skip_database_cleaner: true d
...
@@ -17,11 +17,20 @@ describe Gitlab::Git::Storage::ForkedStorageCheck, skip_database_cleaner: true d
end
end
it
'returns false when the check takes to long'
do
it
'returns false when the check takes to long'
do
allow
(
described_class
).
to
receive
(
:check_filesystem_in_fork
)
do
# We're forking a process here that takes too long
fork
{
sleep
10
}
# It will be killed it's parent process will be killed by it's parent
# and waited for inside `Gitlab::Git::Storage::ForkedStorageCheck.timeout_check`
allow
(
described_class
).
to
receive
(
:check_filesystem_in_process
)
do
Process
.
spawn
(
"sleep 10"
)
end
end
result
=
true
expect
(
described_class
.
storage_available?
(
existing_path
,
0.5
)).
to
be_falsey
runtime
=
Benchmark
.
realtime
do
result
=
described_class
.
storage_available?
(
existing_path
,
0.5
)
end
expect
(
result
).
to
be_falsey
expect
(
runtime
).
to
be
<
1.0
end
end
describe
'when using paths with spaces'
do
describe
'when using paths with spaces'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment