Two bots simultaneously calling `get_joined_members` causes error
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 38/100
Direzione di ricerca
Inizia da set_members in mautrix/client/state_store/asyncpg/store.py ed esamina il relativo percorso PostgreSQL copy_records_to_table insieme ai percorsi executemany per gli altri database. Riproduci chiamate concorrenti a get_joined_members e verifica che gli aggiornamenti concorrenti non producano più errori di chiave duplicata, mantenendo al contempo l’elenco dei membri coerente in tutti i database supportati.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
I'm using get_joined_members() for a bot to determine if a room is a direct message.
If multiple instances of the bot are running, I occasionally get this this error:
Failed to run handler
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/mautrix/client/syncer.py", line 235, in _catch_errors
await handler(data)
File "/usr/local/lib/python3.11/site-packages/mautrix/crypto/machine.py", line 167, in handle_device_lists
await self._fetch_keys(device_lists.changed, include_untracked=False)
File "/usr/local/lib/python3.11/site-packages/mautrix/crypto/device_lists.py", line 80, in _fetch_keys
await self.crypto_store.put_devices(user_id, new_devices)
File "/usr/local/lib/python3.11/site-packages/mautrix/crypto/store/asyncpg/store.py", line 615, in put_devices
await conn.copy_records_to_table("crypto_device", records=data, columns=columns)
File "/usr/local/lib/python3.11/site-packages/mautrix/util/async_db/connection.py", line 38, in wrapper
ret = await func(self, arg, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/mautrix/util/async_db/connection.py", line 151, in copy_records_to_table
return await self.wrapped.copy_records_to_table(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/asyncpg/connection.py", line 983, in copy_records_to_table
return await self._protocol.copy_in(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "asyncpg/protocol/protocol.pyx", line 529, in copy_in
asyncpg.exceptions.UniqueViolationError: duplicate key value violates unique constraint "crypto_device_pkey"
DETAIL: Key (user_id, device_id)=(@xxxx:yyyy, zzzz) already exists.
It looks like this is happening because set_members works by deleting a room's members from the database and then inserting the new member list returned by get_joined_members, so if this function is simultaneously called by two bots, the old rows and removed at the same time and then duplicate new rows are added which results in the error.
It seems like this could be fixed by adding an ON CONFLICT (user_id, device_id) DO NOTHING, but I haven't done a pull request because set_members uses copy_records_to_table for postgresql and executemany for the other databases and I'm not familiar enough with them to be confident.
- Lingua principale
- Python
- Stelle
- 249
- Fork
- 84
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di mautrix/python
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 30/100
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 45/100
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 30/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
Tutte le issue di mautrix/python
Issue simili
-
documentation help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 90/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 90/100
simonw/sqlite-utils#872 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100