Skip to content

Detached model state on render of unmounted context consumer where context provider value does not change. #847

Closed
@Archmonger

Description

@Archmonger

Current Situation

Context should be able to be scoped to conditionally rendered components, and when those subcomponents are removed the deletion of the Context should be handled gracefully.

See: https://github.com/Archmonger/Conreq/blob/d64b3ba879d263b36ab4806d4790d44cefea1045/conreq/_core/components.py#L46-L64

Traceback (most recent call last):
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\django\contrib\staticfiles\handlers.py", line 101, in __call__
    return await self.application(scope, receive, send)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\routing.py", line 62, in __call__
    return await application(scope, receive, send)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\security\websocket.py", line 37, in __call__
    return await self.application(scope, receive, send)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\sessions.py", line 47, in __call__
    return await self.inner(dict(scope, cookies=cookies), receive, send)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\sessions.py", line 263, in __call__
    return await self.inner(wrapper.scope, receive, wrapper.send)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\sessions.py", line 47, in __call__
    return await self.inner(dict(scope, cookies=cookies), receive, send)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\sessions.py", line 263, in __call__
    return await self.inner(wrapper.scope, receive, wrapper.send)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\auth.py", line 185, in __call__
    return await super().__call__(scope, receive, send)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\middleware.py", line 24, in __call__
    return await self.inner(scope, receive, send)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\routing.py", line 116, in __call__
    return await application(
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\consumer.py", line 94, in app
    return await consumer(scope, receive, send)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\consumer.py", line 62, in __call__
    await await_many_dispatch([receive], self.dispatch)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\utils.py", line 50, in await_many_dispatch
    await dispatch(result)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\consumer.py", line 73, in dispatch
    await handler(message)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\channels\generic\websocket.py", line 238, in websocket_disconnect
    await self.disconnect(message["code"])
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\django_idom\websocket\consumer.py", line 42, in disconnect
    await self._idom_dispatcher_future
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\django_idom\websocket\consumer.py", line 76, in _run_dispatch_loop
    await serve_json_patch(
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\idom\core\serve.py", line 44, in serve_json_patch
    async with create_task_group() as task_group:
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\anyio\_backends\_asyncio.py", line 662, in __aexit__
    raise exceptions[0]
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\idom\core\serve.py", line 84, in _single_outgoing_loop
    await send(await render_json_patch(layout))
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\idom\core\serve.py", line 53, in render_json_patch
    return VdomJsonPatch.create_from(await layout.render())
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\idom\core\layout.py", line 153, in render
    result = await self._debug_render()
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\idom\core\layout.py", line 142, in render
    return self._create_layout_update(model_state)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\idom\core\layout.py", line 161, in _create_layout_update
    new_state = _copy_component_model_state(old_state)
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\idom\core\layout.py", line 528, in _copy_component_model_state
    parent: Optional[_ModelState] = old_model_state.parent
  File "C:\Users\Markg\Documents\Repositories\Conreq\.venv\lib\site-packages\idom\core\layout.py", line 661, in parent
    assert parent is not None, "detached model state"
AssertionError: detached model state

Can be replicated by pulling the latest Conreq branch, and clicking between the any of the "settings" sidebar tabs, then going to a different tab.

Proposed Actions

Determine root cause and fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions