Spaces:
Running
Running
Prayer: 0be4ca6 engine; no concurrent cap (MAX=0)
Browse files- ingest.py +10 -4
- youtube_manager.py +8 -3
ingest.py
CHANGED
|
@@ -35,12 +35,15 @@ def max_concurrent_relays():
|
|
| 35 |
not a pass. Operators may raise MAX_CONCURRENT_RELAYS; health reports the
|
| 36 |
value actually in force. Ceiling 8 is only a fork-bomb guard.
|
| 37 |
"""
|
| 38 |
-
raw = os.getenv('MAX_CONCURRENT_RELAYS')
|
|
|
|
|
|
|
| 39 |
try:
|
| 40 |
n = int(str(raw).strip())
|
| 41 |
except (TypeError, ValueError):
|
| 42 |
-
n =
|
| 43 |
-
|
|
|
|
| 44 |
|
| 45 |
|
| 46 |
def format_session_title(broadcaster, when=None):
|
|
@@ -147,7 +150,10 @@ class RelayHub:
|
|
| 147 |
with self.lock:
|
| 148 |
n = sum(1 for u, v in self.slots.items()
|
| 149 |
if u != except_user and self._ffmpeg_alive(v))
|
| 150 |
-
|
|
|
|
|
|
|
|
|
|
| 151 |
|
| 152 |
def env_key_busy(self, except_user=None):
|
| 153 |
"""A single env stream key can only accept one publisher (any owner)."""
|
|
|
|
| 35 |
not a pass. Operators may raise MAX_CONCURRENT_RELAYS; health reports the
|
| 36 |
value actually in force. Ceiling 8 is only a fork-bomb guard.
|
| 37 |
"""
|
| 38 |
+
raw = os.getenv('MAX_CONCURRENT_RELAYS')
|
| 39 |
+
if raw is None or str(raw).strip() == '':
|
| 40 |
+
raw = os.getenv('YOUTUBE_MAX_EVENTS') or '0'
|
| 41 |
try:
|
| 42 |
n = int(str(raw).strip())
|
| 43 |
except (TypeError, ValueError):
|
| 44 |
+
n = 0
|
| 45 |
+
# 0 = every LIVE account may copy (one FFmpeg per user). No hidden ceiling.
|
| 46 |
+
return n if n > 0 else 0
|
| 47 |
|
| 48 |
|
| 49 |
def format_session_title(broadcaster, when=None):
|
|
|
|
| 150 |
with self.lock:
|
| 151 |
n = sum(1 for u, v in self.slots.items()
|
| 152 |
if u != except_user and self._ffmpeg_alive(v))
|
| 153 |
+
cap = max_concurrent_relays()
|
| 154 |
+
if cap <= 0:
|
| 155 |
+
return False
|
| 156 |
+
return n >= cap
|
| 157 |
|
| 158 |
def env_key_busy(self, except_user=None):
|
| 159 |
"""A single env stream key can only accept one publisher (any owner)."""
|
youtube_manager.py
CHANGED
|
@@ -45,7 +45,12 @@ class ManagedYouTube:
|
|
| 45 |
# إيقاع إعادة المحاولة عندما تكون تيك توك «مباشرة» بلا مرشّحات (لحظات انتقال جولات PK):
|
| 46 |
# كان الحدث ينتظر دورة المشغّل كاملة (30ث) مع كاش رصد قديم، فبدا «معلّقًا على يوتيوب».
|
| 47 |
self.source_retry=max(5,int(os.getenv('YOUTUBE_SOURCE_RETRY',str(min(15,self.scan)))))
|
| 48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
self.last_logged=None;self.status_text='متوقف'
|
| 50 |
# Written in _select_source / _skip_note; declared here so a fresh manager never has to
|
| 51 |
# rely on getattr() defaults (and so the reason survives the first skip).
|
|
@@ -1233,7 +1238,7 @@ class ManagedYouTube:
|
|
| 1233 |
return False
|
| 1234 |
if any(e.get('username')==user for e in d['events'].values()):
|
| 1235 |
return False
|
| 1236 |
-
if len(d['events'])>=self.max_events:
|
| 1237 |
return False
|
| 1238 |
key=user+':'+str(obs['room_id'])
|
| 1239 |
entry=next((h for h in d['history'] if h.get('session_key')==key),None)
|
|
@@ -1328,7 +1333,7 @@ class ManagedYouTube:
|
|
| 1328 |
# 2) Discover new live sessions, one event per account, up to the concurrency cap.
|
| 1329 |
cap=self.max_events;active=len(d['events']);capped=False
|
| 1330 |
for user in accounts:
|
| 1331 |
-
if active>=cap:capped=True;break
|
| 1332 |
if any(e['username']==user for e in d['events'].values()):continue
|
| 1333 |
# رفض الهوية (توكن منتهٍ) لا يُعالَج بوتيرة الرصد: كل دورة كانت تضرب تيك توك
|
| 1334 |
# برفض مؤكد (~10/د على خمسة حسابات) وتُغرق السجل حتى وهو مكبوت. إيقاف لكل
|
|
|
|
| 45 |
# إيقاع إعادة المحاولة عندما تكون تيك توك «مباشرة» بلا مرشّحات (لحظات انتقال جولات PK):
|
| 46 |
# كان الحدث ينتظر دورة المشغّل كاملة (30ث) مع كاش رصد قديم، فبدا «معلّقًا على يوتيوب».
|
| 47 |
self.source_retry=max(5,int(os.getenv('YOUTUBE_SOURCE_RETRY',str(min(15,self.scan)))))
|
| 48 |
+
try:
|
| 49 |
+
self.max_events=int(os.getenv('YOUTUBE_MAX_EVENTS') or 0)
|
| 50 |
+
except (TypeError, ValueError):
|
| 51 |
+
self.max_events=0
|
| 52 |
+
if self.max_events<=0:
|
| 53 |
+
self.max_events=int(max_concurrent_relays() or 0)
|
| 54 |
self.last_logged=None;self.status_text='متوقف'
|
| 55 |
# Written in _select_source / _skip_note; declared here so a fresh manager never has to
|
| 56 |
# rely on getattr() defaults (and so the reason survives the first skip).
|
|
|
|
| 1238 |
return False
|
| 1239 |
if any(e.get('username')==user for e in d['events'].values()):
|
| 1240 |
return False
|
| 1241 |
+
if self.max_events>0 and len(d['events'])>=self.max_events:
|
| 1242 |
return False
|
| 1243 |
key=user+':'+str(obs['room_id'])
|
| 1244 |
entry=next((h for h in d['history'] if h.get('session_key')==key),None)
|
|
|
|
| 1333 |
# 2) Discover new live sessions, one event per account, up to the concurrency cap.
|
| 1334 |
cap=self.max_events;active=len(d['events']);capped=False
|
| 1335 |
for user in accounts:
|
| 1336 |
+
if cap>0 and active>=cap:capped=True;break
|
| 1337 |
if any(e['username']==user for e in d['events'].values()):continue
|
| 1338 |
# رفض الهوية (توكن منتهٍ) لا يُعالَج بوتيرة الرصد: كل دورة كانت تضرب تيك توك
|
| 1339 |
# برفض مؤكد (~10/د على خمسة حسابات) وتُغرق السجل حتى وهو مكبوت. إيقاف لكل
|