digital-fabric / extralite

Ruby on SQLite
http://www.rubydoc.info/gems/extralite
MIT License
253 stars 8 forks source link

Add GVL mode #39

Closed noteflakes closed 10 months ago

noteflakes commented 11 months ago

In response to #38, this PR adds three different GVL modes for use when running queries:

The backup API always releases the GVL while backing up the DB.

noteflakes commented 10 months ago

Hey @gschlager would you like to have a look and tell me what you think?

Some more thoughts:

gschlager commented 10 months ago

Overall I like these changes. Though the tests look a bit brittle and it doesn't seem like the tests are able to detect the difference between :release and :hybrid right now.

I kinda like the idea of having a gvl_release_threshold and I think it's fine to keep only the :hybrid mode in this case. I like the flexibility of it. But lets suggest good values for various use cases in the documentation.

I'd say having the setting on the DB instead of globally is a good choice. I can imagine a use case where an app switches between single and multithreading and in that case it might make sense to configure this on the DB connection level instead of globally.

noteflakes commented 10 months ago

Though the tests look a bit brittle and it doesn't seem like the tests are able to detect the difference between :release and :hybrid right now.

I agree. I couldn't find a way to make SQLite sleep or make a long calculation on each row. Any idea?

gschlager commented 10 months ago

I agree. I couldn't find a way to make SQLite sleep or make a long calculation on each row. Any idea?

Unfortunately not. I tried a couple of things, but :hybrid mode seems impossible to test reliably. I wonder if the tests are any good if they can't reliably test the gvl_mode.

fractaledmind commented 10 months ago

@dbackeus shared this technique with me for getting SQLite to "sleep":

-- Since SQLite doesn't have a sleep function, we'll use a recursive CTE
-- which takes approximately 1 second to execute.
WITH RECURSIVE r(i) AS (
  VALUES(0)
  UNION ALL
  SELECT i FROM r
  LIMIT 10000000
)
SELECT i FROM r WHERE i = 1;
noteflakes commented 10 months ago

Closed in favor of #46.