Repository: matrix-org/synapse

Issue:
Own presence shown as offline after a while with presence writer worker enabled
### Description

We're trialing presence workers on a few EMS hosts and for a while the new presence writer worker worked fine. After a few days, both of the hosts stopped reporting presence online for the user themselves. A restart of Synapse made presence show correctly for self again.

### Version information

- **Version**: v1.34.0
- **Platform**: EMS/Docker

Please ping for host names for logs access.


Discussion:
I think this is more widespread than just your own presence; from vector.modular.im I'm seeing both my work account (on vector.modular.im) and my personal account (on abolivier.bzh) as offline even though they're both online.
Yeah currently I can't see anyone from vector online even if I'm actively talking to one in a dm.
I wonder if this is related to https://github.com/matrix-org/synapse/issues/9962 (fixed in v1.35.0).
I think it might be yes.
Have updated to v1.35.0, will confirm whether issue disappears.
Unfortunately the issue persists. After restart I saw myself online (on federator.dev) for a while and am now offline again. Also I still see no one online from vector, which also was updated to v1.35.0.

I can see presence of some people on their own HS's who may or may not be running a presence worker (assuming that matters). These include @erikjohnston and @daenney who consistently show online for me.

Could this be a configuration thing, given both federator and vector run in EMS? I could try remove the presence workers to see if that matters?
In my case I'm not running with a presence worker. My HS is the all-in-one no workers anywhere setup.

Resolving patch:
diff --git a/synapse/storage/databases/main/presence.py b/synapse/storage/databases/main/presence.py
--- a/synapse/storage/databases/main/presence.py
+++ b/synapse/storage/databases/main/presence.py
@@ -50,7 +50,7 @@ def __init__(
                 instance_name=self._instance_name,
                 tables=[("presence_stream", "instance_name", "stream_id")],
                 sequence_name="presence_stream_sequence",
-                writers=hs.config.worker.writers.to_device,
+                writers=hs.config.worker.writers.presence,
             )
         else:
             self._presence_id_gen = StreamIdGenerator(
diff --git a/synapse/storage/util/id_generators.py b/synapse/storage/util/id_generators.py
--- a/synapse/storage/util/id_generators.py
+++ b/synapse/storage/util/id_generators.py
@@ -397,6 +397,11 @@ def get_next(self):
                 # ... persist event ...
         """
 
+        # If we have a list of instances that are allowed to write to this
+        # stream, make sure we're in it.
+        if self._writers and self._instance_name not in self._writers:
+            raise Exception("Tried to allocate stream ID on non-writer")
+
         return _MultiWriterCtxManager(self)
 
     def get_next_mult(self, n: int):
@@ -406,6 +411,11 @@ def get_next_mult(self, n: int):
                 # ... persist events ...
         """
 
+        # If we have a list of instances that are allowed to write to this
+        # stream, make sure we're in it.
+        if self._writers and self._instance_name not in self._writers:
+            raise Exception("Tried to allocate stream ID on non-writer")
+
         return _MultiWriterCtxManager(self, n)
 
     def get_next_txn(self, txn: LoggingTransaction):
@@ -416,6 +426,11 @@ def get_next_txn(self, txn: LoggingTransaction):
             # ... persist event ...
         """
 
+        # If we have a list of instances that are allowed to write to this
+        # stream, make sure we're in it.
+        if self._writers and self._instance_name not in self._writers:
+            raise Exception("Tried to allocate stream ID on non-writer")
+
         next_id = self._load_next_id_txn(txn)
 
         with self._lock:


Test patch: