fix: mumble disconnect loop from stale socket and dead parent thread
Two issues causing ~2min reconnect cycles: 1. pymumble captures threading.current_thread() as parent_thread at init. Since we construct it in a run_in_executor thread, the parent dies after _connect_sync returns, triggering pymumble's loop exit. Fix: point parent_thread at threading.main_thread(). 2. pymumble's init_connection() drops the control_socket reference without closing it. The lingering TCP connection makes Murmur kick the new session with "connected from another device". Fix: patch init_connection to close the old socket before reconnecting.
This commit is contained in:
@@ -43,3 +43,27 @@ new_opus = "lib_location = find_library('opus') or 'libopus.so.0'"
|
|||||||
assert old_opus in src, "opuslib find_library patch target not found"
|
assert old_opus in src, "opuslib find_library patch target not found"
|
||||||
p.write_text(src.replace(old_opus, new_opus))
|
p.write_text(src.replace(old_opus, new_opus))
|
||||||
print("opuslib musl patch applied")
|
print("opuslib musl patch applied")
|
||||||
|
|
||||||
|
# -- pymumble: close old socket before reconnecting --
|
||||||
|
# init_connection() drops control_socket reference without closing it.
|
||||||
|
# The lingering TCP connection causes Murmur to kick the new session
|
||||||
|
# with "You connected to the server from another device".
|
||||||
|
p = pathlib.Path(f"{site}/pymumble_py3/mumble.py")
|
||||||
|
src = p.read_text()
|
||||||
|
|
||||||
|
old_init = """\
|
||||||
|
self.connected = PYMUMBLE_CONN_STATE_NOT_CONNECTED
|
||||||
|
self.control_socket = None"""
|
||||||
|
|
||||||
|
new_init = """\
|
||||||
|
self.connected = PYMUMBLE_CONN_STATE_NOT_CONNECTED
|
||||||
|
if getattr(self, 'control_socket', None) is not None:
|
||||||
|
try:
|
||||||
|
self.control_socket.close()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
self.control_socket = None"""
|
||||||
|
|
||||||
|
assert old_init in src, "pymumble init_connection socket patch target not found"
|
||||||
|
p.write_text(src.replace(old_init, new_init))
|
||||||
|
print("pymumble reconnect socket patch applied")
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import struct
|
import struct
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -176,6 +177,11 @@ class MumbleBot:
|
|||||||
certfile=self._certfile, keyfile=self._keyfile,
|
certfile=self._certfile, keyfile=self._keyfile,
|
||||||
reconnect=True,
|
reconnect=True,
|
||||||
)
|
)
|
||||||
|
# pymumble captures threading.current_thread() as parent_thread at
|
||||||
|
# init time. Since we run in an executor thread (which is transient),
|
||||||
|
# the parent check in pymumble's loop would see a dead thread and
|
||||||
|
# disconnect. Point it at the main thread instead.
|
||||||
|
self._mumble.parent_thread = threading.main_thread()
|
||||||
self._mumble.callbacks.set_callback(
|
self._mumble.callbacks.set_callback(
|
||||||
PYMUMBLE_CLBK_TEXTMESSAGERECEIVED,
|
PYMUMBLE_CLBK_TEXTMESSAGERECEIVED,
|
||||||
self._on_text_message,
|
self._on_text_message,
|
||||||
|
|||||||
Reference in New Issue
Block a user