Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disconnect connection and close database #25

Open
hl opened this issue Oct 25, 2024 · 4 comments
Open

Disconnect connection and close database #25

hl opened this issue Oct 25, 2024 · 4 comments

Comments

@hl
Copy link

hl commented Oct 25, 2024

First of all, many thanks for this great library.

I was wondering if duckdb_disconnect and duckdb_close are on the roadmap.

My use case would be to start a db and connection (in memory), load data, query it and shut it down again to free up the allocated memory.

(My C knowledge is non-existent otherwise I would have opened a PR)

@AlexR2D2
Copy link
Owner

Thanks!
Please, see similar issues, next

@hl hl closed this as completed Oct 29, 2024
@ruslandoga
Copy link

ruslandoga commented Nov 2, 2024

👋 @AlexR2D2

Just a question: since the NIF resource destructors run on the main scheduler, doesn't it have a slight issue with (unlikely) scheduler blocking?

For reference, here are the timings on my system using C API bindings, closing an in-memory database (for the first time) takes 4 ms (which is probably fine, even on a main scheduler).

iex> {_, db} = :timer.tc fn -> DuxDB.open(":memory:") end
{61964, #Reference<0.1637195888.2898133009.42168>}
iex> {_, conn} = :timer.tc fn -> DuxDB.connect(db) end
{92, #Reference<0.1637195888.2898132993.42140>}
iex> {_, stmt} = :timer.tc fn -> DuxDB.prepare(conn, "select 1") end
{7939, #Reference<0.1637195888.2898133008.41788>}
iex> {_, :ok} = :timer.tc fn -> DuxDB.destroy_prepare(stmt) end
{53, :ok}
iex> {_, :ok} = :timer.tc fn -> DuxDB.disconnect(conn) end
{82, :ok}
iex> {_, :ok} = :timer.tc fn -> DuxDB.close(db) end
{4514, :ok}

Subsequent executions of this snippet show lower timings for open, prepare, and sometimes for close too.

iex> {_, db} = :timer.tc fn -> DuxDB.open(":memory:") end
{6002, #Reference<0.1637195888.2898133009.42198>}
iex> {_, conn} = :timer.tc fn -> DuxDB.connect(db) end
{123, #Reference<0.1637195888.2898132993.43088>}
iex> {_, stmt} = :timer.tc fn -> DuxDB.prepare(conn, "select 1") end
{401, #Reference<0.1637195888.2898133008.41794>}
iex> {_, :ok} = :timer.tc fn -> DuxDB.destroy_prepare(stmt) end
{25, :ok}
iex> {_, :ok} = :timer.tc fn -> DuxDB.disconnect(conn) end
{58, :ok}
iex> {_, :ok} = :timer.tc fn -> DuxDB.close(db) end
{4360, :ok}

@AlexR2D2
Copy link
Owner

AlexR2D2 commented Nov 2, 2024

👋 @ruslandoga yes, you are right, this can happen. In addition, you may need to close DB explicitly, for example to send db file somebody or archive it and open new db file, thus, explicit closing can be required by business logic, so I will add this close functions to the lib. Thanks!

@ruslandoga
Copy link

ruslandoga commented Dec 21, 2024

There was a recent discussion about this problem on Erlang forums: https://erlangforums.com/t/how-to-deal-with-destructors-that-can-take-a-while-to-run-and-possibly-block-the-scheduler/4290

DuckDB is probably safe from these issues but I still wanted to share since it's interesting :)

@AlexR2D2 AlexR2D2 reopened this Dec 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants