Skip to content

use_mutation and use_query are not async #135

Closed
@Archmonger

Description

@Archmonger

Current Situation

Due to Django ORM's poor async support, use_mutation and use_query rely on database_sync_to_async with thread_sensitive=True.

This unfortunately means that only one use_query call can execute at a time. We should write the use_query hook to be natively async and support async function calls.

Proposed Actions

For async mutations and query functions:

  • Have the developer handle async safety where needed

For sync mutations and query functions:

  • Use thread_senstive=True by default, since sync code has a reasonable expectation of thread blocking.
  • Create a QueryOptions parameter to customize the value of thread_senstive.

Discussed in #132

Originally posted by numpde March 14, 2023
Consider the following component, which is displayed using {% component ... %} from a template in a browser tab A. On button-click, a lengthy use_mutation is executed.

What I find suspicious is that a copy of the component (or any component, for that matter?) would not load in a parallel tab B until the mutation in A completes.

from typing import Callable

from django.utils.timezone import now

from django_idom.hooks import use_mutation
from idom import html, use_state, component


def work(t0, trg: Callable):
    import time
    time.sleep(10)
    trg(now() - t0)


@component
def Main():
    sleeper = use_mutation(work)
    elapsed = use_state(None)

    return html.div(
        html.button(
            {
                'on_click': (lambda e: sleeper.execute(t0=now(), trg=elapsed.set_value)),
                'class_name': "btn btn-primary",
                'disabled': sleeper.loading,
            },
            f"Elapsed: {elapsed.value}" if elapsed.value else "use_mutation"
        ),
    )

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions