mirror of
https://github.com/simonw/datasette.git
synced 2026-05-30 05:37:01 +02:00
Replace Janus queue with asyncio.Future
Closes #1752 AI generated patch explanation: https://gisthost.github.io/?e2b8d9c7666e988b5c003ff5e5ef3098
This commit is contained in:
parent
46d90a0b88
commit
3110faa0ba
5 changed files with 140 additions and 47 deletions
|
|
@ -2,9 +2,12 @@
|
|||
Tests for the datasette.database.Database class
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from types import SimpleNamespace
|
||||
from datasette.app import Datasette
|
||||
from datasette.database import Database, Results, MultipleValues
|
||||
from datasette.database import DatasetteClosedError
|
||||
from datasette.database import _deliver_write_result
|
||||
from datasette.utils.sqlite import sqlite3, sqlite_version
|
||||
from datasette.utils import Column
|
||||
import pytest
|
||||
|
|
@ -590,6 +593,37 @@ async def test_execute_write_fn_connection_exception(tmpdir, app_client):
|
|||
app_client.ds.remove_database("immutable-db")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_deliver_write_result_leaves_done_future_alone():
|
||||
loop = asyncio.get_running_loop()
|
||||
reply_future = loop.create_future()
|
||||
reply_future.set_result("original")
|
||||
task = SimpleNamespace(loop=loop, reply_future=reply_future)
|
||||
|
||||
# The write thread can finish after the caller has stopped waiting for the
|
||||
# result. Delivery should notice that the future is already resolved and
|
||||
# leave the caller's outcome alone instead of raising InvalidStateError.
|
||||
_deliver_write_result(task, "replacement", None)
|
||||
await asyncio.sleep(0)
|
||||
|
||||
assert reply_future.result() == "original"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_deliver_write_result_ignores_closed_loop():
|
||||
closed_loop = asyncio.new_event_loop()
|
||||
closed_loop.close()
|
||||
reply_future = asyncio.get_running_loop().create_future()
|
||||
task = SimpleNamespace(loop=closed_loop, reply_future=reply_future)
|
||||
|
||||
# If the event loop that submitted the write has gone away, the write
|
||||
# thread should drop the result rather than crash while reporting back to
|
||||
# that closed loop.
|
||||
_deliver_write_result(task, "result", None)
|
||||
|
||||
assert not reply_future.done()
|
||||
|
||||
|
||||
def table_exists(conn, name):
|
||||
return bool(
|
||||
conn.execute(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
Tests for the write_wrapper plugin hook.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from dataclasses import dataclass
|
||||
from datasette.app import Datasette
|
||||
from datasette.events import Event
|
||||
|
|
@ -633,8 +634,6 @@ async def test_track_event_with_block_false(ds_with_event_tracking):
|
|||
assert task_id is not None
|
||||
|
||||
# Give the background task time to complete
|
||||
import asyncio
|
||||
|
||||
for _ in range(50):
|
||||
if ds._tracked_events:
|
||||
break
|
||||
|
|
@ -644,6 +643,30 @@ async def test_track_event_with_block_false(ds_with_event_tracking):
|
|||
assert ds._tracked_events[0].message == "non-blocking"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_track_event_with_block_false_discarded_on_exception(
|
||||
ds_with_event_tracking,
|
||||
):
|
||||
"""Events queued by a non-blocking write are discarded if the write fails."""
|
||||
ds = ds_with_event_tracking
|
||||
db = ds.get_database("test")
|
||||
|
||||
def my_write(conn, track_event):
|
||||
track_event(DummyEvent(actor=None, message="should not fire"))
|
||||
raise ValueError("deliberate error")
|
||||
|
||||
task_id = await db.execute_write_fn(my_write, block=False)
|
||||
assert task_id is not None
|
||||
|
||||
# A following blocking write proves the failed non-blocking task has
|
||||
# completed; one more loop turn lets its event-dispatch task observe the
|
||||
# exception and exit.
|
||||
await db.execute_write_fn(lambda conn: conn.execute("select 1"))
|
||||
await asyncio.sleep(0)
|
||||
|
||||
assert ds._tracked_events == []
|
||||
|
||||
|
||||
# --- Tests for RenameTableEvent detection ---
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue