mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Clean up compatibility with Pyodide (#1736)
* Optional uvicorn import for Pyodide, refs #1733 * --setting num_sql_threads 0 to disable threading, refs #1735
This commit is contained in:
parent
a29c127789
commit
3f00a29141
4 changed files with 42 additions and 4 deletions
|
|
@ -288,9 +288,12 @@ class Datasette:
|
|||
self._settings = dict(DEFAULT_SETTINGS, **(settings or {}))
|
||||
self.renderers = {} # File extension -> (renderer, can_render) functions
|
||||
self.version_note = version_note
|
||||
self.executor = futures.ThreadPoolExecutor(
|
||||
max_workers=self.setting("num_sql_threads")
|
||||
)
|
||||
if self.setting("num_sql_threads") == 0:
|
||||
self.executor = None
|
||||
else:
|
||||
self.executor = futures.ThreadPoolExecutor(
|
||||
max_workers=self.setting("num_sql_threads")
|
||||
)
|
||||
self.max_returned_rows = self.setting("max_returned_rows")
|
||||
self.sql_time_limit_ms = self.setting("sql_time_limit_ms")
|
||||
self.page_size = self.setting("default_page_size")
|
||||
|
|
@ -862,6 +865,8 @@ class Datasette:
|
|||
]
|
||||
|
||||
def _threads(self):
|
||||
if self.setting("num_sql_threads") == 0:
|
||||
return {"num_threads": 0, "threads": []}
|
||||
threads = list(threading.enumerate())
|
||||
d = {
|
||||
"num_threads": len(threads),
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ class Database:
|
|||
self._cached_table_counts = None
|
||||
self._write_thread = None
|
||||
self._write_queue = None
|
||||
# These are used when in non-threaded mode:
|
||||
self._read_connection = None
|
||||
self._write_connection = None
|
||||
if not self.is_mutable and not self.is_memory:
|
||||
p = Path(path)
|
||||
self.hash = inspect_hash(p)
|
||||
|
|
@ -134,6 +137,14 @@ class Database:
|
|||
return results
|
||||
|
||||
async def execute_write_fn(self, fn, block=True):
|
||||
if self.ds.executor is None:
|
||||
# non-threaded mode
|
||||
if self._write_connection is None:
|
||||
self._write_connection = self.connect(write=True)
|
||||
self.ds._prepare_connection(self._write_connection, self.name)
|
||||
return fn(self._write_connection)
|
||||
|
||||
# threaded mode
|
||||
task_id = uuid.uuid5(uuid.NAMESPACE_DNS, "datasette.io")
|
||||
if self._write_queue is None:
|
||||
self._write_queue = queue.Queue()
|
||||
|
|
@ -177,6 +188,14 @@ class Database:
|
|||
task.reply_queue.sync_q.put(result)
|
||||
|
||||
async def execute_fn(self, fn):
|
||||
if self.ds.executor is None:
|
||||
# non-threaded mode
|
||||
if self._read_connection is None:
|
||||
self._read_connection = self.connect()
|
||||
self.ds._prepare_connection(self._read_connection, self.name)
|
||||
return fn(self._read_connection)
|
||||
|
||||
# threaded mode
|
||||
def in_thread():
|
||||
conn = getattr(connections, self.name, None)
|
||||
if not conn:
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ Maximum number of threads in the thread pool Datasette uses to execute SQLite qu
|
|||
|
||||
datasette mydatabase.db --setting num_sql_threads 10
|
||||
|
||||
Setting this to 0 turns off threaded SQL queries entirely - useful for environments that do not support threading such as `Pyodide <https://pyodide.org/>`__.
|
||||
|
||||
.. _setting_allow_facet:
|
||||
|
||||
allow_facet
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
Tests for the datasette.app.Datasette class
|
||||
"""
|
||||
from datasette.app import Datasette
|
||||
from datasette.app import Datasette, Database
|
||||
from itsdangerous import BadSignature
|
||||
from .fixtures import app_client
|
||||
import pytest
|
||||
|
|
@ -63,3 +63,15 @@ async def test_datasette_constructor():
|
|||
"hash": None,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_num_sql_threads_zero():
|
||||
ds = Datasette([], memory=True, settings={"num_sql_threads": 0})
|
||||
db = ds.add_database(Database(ds, memory_name="test_num_sql_threads_zero"))
|
||||
await db.execute_write("create table t(id integer primary key)")
|
||||
await db.execute_write("insert into t (id) values (1)")
|
||||
response = await ds.client.get("/-/threads.json")
|
||||
assert response.json() == {"num_threads": 0, "threads": []}
|
||||
response2 = await ds.client.get("/test_num_sql_threads_zero/t.json?_shape=array")
|
||||
assert response2.json() == [{"id": 1}]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue