Skip to content

Commit

Permalink
Merge pull request #456 from fractaledmind/fix-busy_handler_timeout-t…
Browse files Browse the repository at this point in the history
…ests

busy_handler_timeout pt2
  • Loading branch information
tenderlove committed Jan 10, 2024
2 parents 21db633 + 75893cd commit 9cff42b
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
19 changes: 19 additions & 0 deletions lib/sqlite3/database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,25 @@ def readonly?
@readonly
end

# Sets a #busy_handler that releases the GVL between retries,
# but only retries up to the indicated number of +milliseconds+.
# This is an alternative to #busy_timeout, which holds the GVL
# while SQLite sleeps and retries.
def busy_handler_timeout=( milliseconds )
timeout_seconds = milliseconds.fdiv(1000)

busy_handler do |count|
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
if count.zero?
@timeout_deadline = now + timeout_seconds
elsif now > @timeout_deadline
next false
else
sleep(0.001)
end
end
end

# A helper class for dealing with custom functions (see #create_function,
# #create_aggregate, and #create_aggregate_handler). It encapsulates the
# opaque function object that represents the current invocation. It also
Expand Down
38 changes: 38 additions & 0 deletions test/test_integration_pending.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,42 @@ def test_busy_timeout

assert_operator time.real * 1000, :>=, 1000
end

def test_busy_handler_timeout_releases_gvl
work = []

Thread.new do
while true
sleep 0.1
work << '.'
end
end
sleep 1

@db.busy_handler_timeout = 1000
busy = Mutex.new
busy.lock

t = Thread.new do
begin
db2 = SQLite3::Database.open( "test.db" )
db2.transaction( :exclusive ) do
busy.lock
end
ensure
db2.close if db2
end
end
sleep 1

assert_raises( SQLite3::BusyException ) do
work << '|'
@db.execute "insert into foo (b) values ( 'from 2' )"
end

busy.unlock
t.join

assert work.size - work.find_index('|') > 3
end
end

0 comments on commit 9cff42b

Please sign in to comment.