Skip to content

Commit

Permalink
Add note about calling interrupt and close immediately
Browse files Browse the repository at this point in the history
Closes: #315

You can not call close immediately after interrupt. It will result in
undefined behavior. Instead, shim a small `Process.sleep/1` in and it
should mitigate the issue.
  • Loading branch information
warmwaffles committed Jan 21, 2025
1 parent f09f773 commit 2fe6882
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

- changed: Removed `Exqlite.bind/3`, please use `bind/2` instead.
- changed: Improved multi-threaded access to underlying sqlite resource.
- changed: Document issue with calling `close/1` immediately after calling
`interrupt/1`. If you encounter the issue where the entire BEAM crashes, put
a short sleep between the call to `interrupt/1` and `close/1`.

## v0.28.0

Expand Down
9 changes: 9 additions & 0 deletions lib/exqlite/sqlite3.ex
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ defmodule Exqlite.Sqlite3 do

@doc """
Interrupt a long-running query.
> #### Warning {: .warning}
> If you are going to interrupt a long running process, it is unsafe to call
> `close/1` immediately after. You run the risk of undefined behavior. This
> is a limitation of the sqlite library itself. Please see the documentation
> https://www.sqlite.org/c3ref/interrupt.html for more information.
>
> If close must be called after, it is best to put a short sleep in order to
> let sqlite finish doing its book keeping.
"""
@spec interrupt(db() | nil) :: :ok | {:error, reason()}
def interrupt(nil), do: :ok
Expand Down
2 changes: 1 addition & 1 deletion test/exqlite/sqlite3_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ defmodule Exqlite.Sqlite3Test do

Process.sleep(100)
:ok = Sqlite3.interrupt(conn)

Process.sleep(100)
:ok = Sqlite3.close(conn)
end
end
Expand Down

0 comments on commit 2fe6882

Please sign in to comment.