Skip to content

Commit

Permalink
Move the discard warning into ForkSafety
Browse files Browse the repository at this point in the history
- Make sure it's only emitted once per fork.
- Try to clarify the warning message.
  • Loading branch information
flavorjones committed Sep 17, 2024
1 parent 5428e22 commit 1cabd3f
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 6 deletions.
5 changes: 0 additions & 5 deletions ext/sqlite3/database.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ close_or_discard_db(sqlite3RubyPtr ctx)
sqlite3_file *sfile;
int status;

rb_warning("An open writable sqlite database connection was inherited from a "
"forked process and is being closed to prevent the risk of corruption. "
"If possible, please close all writable sqlite database connections "
"before forking.");

// release as much heap memory as possible by deallocating non-essential memory
// allocations held by the database library. Memory used to cache database pages to
// improve performance is an example of non-essential memory.
Expand Down
10 changes: 10 additions & 0 deletions lib/sqlite3/fork_safety.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,20 @@ def track(database)
end

def discard
warned = false
@databases.each do |db|
next unless db.weakref_alive?

unless db.closed? || db.readonly?
unless warned
# If you are here, you may want to read
# https://github.com/sparklemotion/sqlite3-ruby/pull/558
warn("#{__FILE__}:#{__LINE__}: warning: " \
"Writable sqlite database connection(s) were inherited from a forked process. " \
"This is unsafe and the connections are being closed to prevent possible data " \
"corruption. Please close writable sqlite database connections before forking.")
warned = true
end
db.close
end
end
Expand Down
2 changes: 1 addition & 1 deletion test/test_database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ def test_fork_discards_an_open_readwrite_connection
assert_equal("ok", assertion.chomp, "closed? did not return true")
assert_equal(1, stderr.count, "unexpected output on stderr: #{stderr.inspect}")
assert_match(
/warning: An open writable sqlite database connection was inherited from a forked process/,
/warning: Writable sqlite database connection\(s\) were inherited from a forked process/,
stderr.first,
"expected warning was not emitted"
)
Expand Down

0 comments on commit 1cabd3f

Please sign in to comment.