Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

State events sent by modules sometimes disappear #10830

Open
@babolivier

Description

@babolivier

I've observed a few times that when a module sends a state event A while processing another state event B in the same room then A might be persisted into the room, then deleted immediately afterwards when B gets persisted. Some time ago I managed to track it down to the state res algorithm (when processing B) returning a state that didn't include A and therefore Synapse deleting A from the room's current state; but that algorithm was a bit of a black box to me back then and I didn't push my investigation further.

Today, seeing I could still reproduce it (at least this morning) I decided to give it another go. However, after some time of digging (and no code change) the bug stopped reproducing. I'm still opening this issue in case I stumble upon it again in the future and want to look into it again (I didn't fix the bug, so it must still be around, though it might be a bit random to reproduce).

The sample module I've been using to test this is:

import time

from synapse.api.constants import EventTypes
from synapse.events import EventBase
from synapse.module_api import ModuleApi
from synapse.types import StateMap


class MySuperModule:
    def __init__(self, config: dict, api: ModuleApi):
        self.api = api

        self.api.register_third_party_rules_callbacks(
            check_event_allowed=self.check_event_allowed,
        )

    async def check_event_allowed(self, event: EventBase, state: StateMap[EventBase]):
        if event.is_state() and event.type == EventTypes.PowerLevels:
            await self.api.create_and_send_event_into_room(
                {
                    "room_id": event.room_id,
                    "sender": event.sender,
                    "type": "bzh.abolivier.test3",
                    "content": {"now": int(time.time())},
                    "state_key": "",
                }
            )

        return True, None

(which roughly reproduces the scenario I've seen it happen in initially)

At the time the workaround I found was to use the check_event_allowed callback, and return the event's get_dict() (without modifying it) to force Synapse to rebuild B and recalculate its context to use updated prev_events.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ModulesModule API: https://matrix-org.github.io/synapse/latest/modules/index.htmlS-MinorBlocks non-critical functionality, workarounds exist.T-DefectBugs, crashes, hangs, security vulnerabilities, or other reported issues.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions