1.0.0+kodimov.13: updates don't stop live TV; IPTV Simple restarts only when idle

- After an add-on update the new service found port 57031 still held by the
  old proxy for a moment and moved to a random port; the stream playing kept
  asking 57031 for its manifest and died a minute later (.49, 2026-11-13).
  The proxy now waits up to 10 s for the port, and SO_REUSEADDR /
  allow_reuse_address are set before binding (upstream set them after, so
  they did nothing).
- IPTV Simple is restarted only when nothing plays and no key was pressed
  for 30 s: on .49 a channel opened during a restart failed with an error.
- After start or update, changed instance files (duplicate removed, refresh
  timer) are picked up by the guide reload instead of a restart of their
  own; the service restarts IPTV Simple itself only if that reload didn't
  happen within 10 minutes. 3 restarts after kodimov.12 -> 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
XoséandClaude Opus 5.5 committed 2026-11-13 15:16:30 +01:00
1 parent 69a37ff064
commit 7873b50203
6 files changed
+63 -15

No files matched your search

+13 -1
View File
@@ -274,6 +274,10 @@ PORT = 57031
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
daemon_threads = True
# KodiMov+: must be set before the server binds (setting it on the
# instance afterwards did nothing): connections of the previous proxy
# left in TIME_WAIT would otherwise keep the port taken
allow_reuse_address = True
class Proxy(object):
started = False
@@ -281,8 +285,8 @@ class Proxy(object):
def check_port(self, port=0, default=False):
try:
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
s.bind((HOST, port))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, port))
return s.getsockname()[1]
except:
return default
@@ -292,6 +296,14 @@ class Proxy(object):
return
port = self.check_port(PORT)
# KodiMov+: when the add-on updates, the previous service may still
# hold the port for a few seconds. Wait for it: a stream that is
# playing keeps asking this port for its manifest, and dies if the
# proxy moves to another one.
for _ in range(20):
if port: break
time.sleep(0.5)
port = self.check_port(PORT)
if not port:
port = self.check_port(0)
LOG('port: {}'.format(port))