portacode 1.3.36__py3-none-any.whl → 1.3.37__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of portacode might be problematic. Click here for more details.
- portacode/_version.py +2 -2
- portacode/connection/handlers/system_handlers.py +25 -6
- portacode/connection/terminal.py +22 -0
- {portacode-1.3.36.dist-info → portacode-1.3.37.dist-info}/METADATA +1 -1
- {portacode-1.3.36.dist-info → portacode-1.3.37.dist-info}/RECORD +9 -9
- {portacode-1.3.36.dist-info → portacode-1.3.37.dist-info}/WHEEL +0 -0
- {portacode-1.3.36.dist-info → portacode-1.3.37.dist-info}/entry_points.txt +0 -0
- {portacode-1.3.36.dist-info → portacode-1.3.37.dist-info}/licenses/LICENSE +0 -0
- {portacode-1.3.36.dist-info → portacode-1.3.37.dist-info}/top_level.txt +0 -0
portacode/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.3.
|
|
32
|
-
__version_tuple__ = version_tuple = (1, 3,
|
|
31
|
+
__version__ = version = '1.3.37'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 3, 37)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
import os
|
|
5
5
|
import platform
|
|
6
|
+
import threading
|
|
7
|
+
import time
|
|
6
8
|
from pathlib import Path
|
|
7
9
|
from typing import Any, Dict
|
|
8
10
|
from portacode import __version__
|
|
@@ -12,6 +14,25 @@ from .base import SyncHandler
|
|
|
12
14
|
|
|
13
15
|
logger = logging.getLogger(__name__)
|
|
14
16
|
|
|
17
|
+
# Global CPU monitoring
|
|
18
|
+
_cpu_percent = 0.0
|
|
19
|
+
_cpu_thread = None
|
|
20
|
+
_cpu_lock = threading.Lock()
|
|
21
|
+
|
|
22
|
+
def _cpu_monitor():
|
|
23
|
+
"""Background thread to update CPU usage every 5 seconds."""
|
|
24
|
+
global _cpu_percent
|
|
25
|
+
while True:
|
|
26
|
+
_cpu_percent = psutil.cpu_percent(interval=5.0)
|
|
27
|
+
|
|
28
|
+
def _ensure_cpu_thread():
|
|
29
|
+
"""Ensure CPU monitoring thread is running (singleton)."""
|
|
30
|
+
global _cpu_thread
|
|
31
|
+
with _cpu_lock:
|
|
32
|
+
if _cpu_thread is None or not _cpu_thread.is_alive():
|
|
33
|
+
_cpu_thread = threading.Thread(target=_cpu_monitor, daemon=True)
|
|
34
|
+
_cpu_thread.start()
|
|
35
|
+
|
|
15
36
|
|
|
16
37
|
def _get_os_info() -> Dict[str, Any]:
|
|
17
38
|
"""Get operating system information with robust error handling."""
|
|
@@ -98,15 +119,13 @@ class SystemInfoHandler(SyncHandler):
|
|
|
98
119
|
"""Get system information including OS details."""
|
|
99
120
|
logger.debug("Collecting system information...")
|
|
100
121
|
|
|
122
|
+
# Ensure CPU monitoring thread is running
|
|
123
|
+
_ensure_cpu_thread()
|
|
124
|
+
|
|
101
125
|
# Collect basic system metrics
|
|
102
126
|
info = {}
|
|
103
127
|
|
|
104
|
-
|
|
105
|
-
info["cpu_percent"] = psutil.cpu_percent(interval=0.1)
|
|
106
|
-
logger.debug("CPU usage: %s%%", info["cpu_percent"])
|
|
107
|
-
except Exception as e:
|
|
108
|
-
logger.warning("Failed to get CPU info: %s", e)
|
|
109
|
-
info["cpu_percent"] = 0.0
|
|
128
|
+
info["cpu_percent"] = _cpu_percent
|
|
110
129
|
|
|
111
130
|
try:
|
|
112
131
|
info["memory"] = psutil.virtual_memory()._asdict()
|
portacode/connection/terminal.py
CHANGED
|
@@ -420,6 +420,14 @@ class TerminalManager:
|
|
|
420
420
|
pass
|
|
421
421
|
self._ctl_task = asyncio.create_task(self._control_loop())
|
|
422
422
|
|
|
423
|
+
# Start periodic system info sender
|
|
424
|
+
if getattr(self, "_system_info_task", None):
|
|
425
|
+
try:
|
|
426
|
+
self._system_info_task.cancel()
|
|
427
|
+
except Exception:
|
|
428
|
+
pass
|
|
429
|
+
self._system_info_task = asyncio.create_task(self._periodic_system_info())
|
|
430
|
+
|
|
423
431
|
# For initial connections, request client sessions after control loop starts
|
|
424
432
|
if is_initial:
|
|
425
433
|
asyncio.create_task(self._initial_connection_setup())
|
|
@@ -518,6 +526,20 @@ class TerminalManager:
|
|
|
518
526
|
# Continue processing other messages
|
|
519
527
|
continue
|
|
520
528
|
|
|
529
|
+
async def _periodic_system_info(self) -> None:
|
|
530
|
+
"""Send system_info event every 10 seconds when clients are connected."""
|
|
531
|
+
while True:
|
|
532
|
+
try:
|
|
533
|
+
await asyncio.sleep(10)
|
|
534
|
+
if self._client_session_manager.has_interested_clients():
|
|
535
|
+
from .handlers.system_handlers import SystemInfoHandler
|
|
536
|
+
handler = SystemInfoHandler(self._control_channel, self._context)
|
|
537
|
+
system_info = handler.execute({})
|
|
538
|
+
await self._send_session_aware(system_info)
|
|
539
|
+
except Exception as exc:
|
|
540
|
+
logger.exception("Error in periodic system info: %s", exc)
|
|
541
|
+
continue
|
|
542
|
+
|
|
521
543
|
async def _send_initial_data_to_clients(self, newly_added_sessions: List[str] = None):
|
|
522
544
|
"""Send initial system info and terminal list to connected clients.
|
|
523
545
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
portacode/README.md,sha256=4dKtpvR8LNgZPVz37GmkQCMWIr_u25Ao63iW56s7Ke4,775
|
|
2
2
|
portacode/__init__.py,sha256=oB3sV1wXr-um-RXio73UG8E5Xx6cF2ZVJveqjNmC-vQ,1086
|
|
3
3
|
portacode/__main__.py,sha256=jmHTGC1hzmo9iKJLv-SSYe9BSIbPPZ2IOpecI03PlTs,296
|
|
4
|
-
portacode/_version.py,sha256=
|
|
4
|
+
portacode/_version.py,sha256=fE8KVhDEsGVP9yYUZTuzgGDIbJx4faKQpSpCa5XjGBY,706
|
|
5
5
|
portacode/cli.py,sha256=eDqcZMVFHKzqqWxedhhx8ylu5WMVCLqeJQkbPR7RcJE,16333
|
|
6
6
|
portacode/data.py,sha256=5-s291bv8J354myaHm1Y7CQZTZyRzMU3TGe5U4hb-FA,1591
|
|
7
7
|
portacode/keypair.py,sha256=PAcOYqlVLOoZTPYi6LvLjfsY6BkrWbLOhSZLb8r5sHs,3635
|
|
@@ -11,7 +11,7 @@ portacode/connection/README.md,sha256=f9rbuIEKa7cTm9C98rCiBbEtbiIXQU11esGSNhSMiJ
|
|
|
11
11
|
portacode/connection/__init__.py,sha256=atqcVGkViIEd7pRa6cP2do07RJOM0UWpbnz5zXjGktU,250
|
|
12
12
|
portacode/connection/client.py,sha256=Uqsy5xzN0j5AY0xkYs2_qd67N7SUopcnpkCbkmOnMgg,9102
|
|
13
13
|
portacode/connection/multiplex.py,sha256=L-TxqJ_ZEbfNEfu1cwxgJ5vUdyRzZjsMy2Kx1diiZys,5237
|
|
14
|
-
portacode/connection/terminal.py,sha256=
|
|
14
|
+
portacode/connection/terminal.py,sha256=5PlEnbEDbVsvuoaduO06PhU_BIZmycNejP80C47ot44,43511
|
|
15
15
|
portacode/connection/handlers/README.md,sha256=HsLZG1QK1JNm67HsgL6WoDg9nxzKXxwkc5fJPFJdX5g,12169
|
|
16
16
|
portacode/connection/handlers/WEBSOCKET_PROTOCOL.md,sha256=xnVrY5uR00z88Q1mBJp-RHVGBoUDS0CWn0PD_D49LDk,74136
|
|
17
17
|
portacode/connection/handlers/__init__.py,sha256=U8OLLKNPZHca03Arhzbqfs2xzDObQD_Ze3zr5j_G_a4,2193
|
|
@@ -22,7 +22,7 @@ portacode/connection/handlers/project_aware_file_handlers.py,sha256=n0M2WmBNWPwz
|
|
|
22
22
|
portacode/connection/handlers/project_state_handlers.py,sha256=v6ZefGW9i7n1aZLq2jOGumJIjYb6aHlPI4m1jkYewm8,1686
|
|
23
23
|
portacode/connection/handlers/registry.py,sha256=qXGE60sYEWg6ZtVQzFcZ5YI2XWR6lMgw4hAL9x5qR1I,6181
|
|
24
24
|
portacode/connection/handlers/session.py,sha256=XWiD4dofzZB9AH7EDqbWeJ-1CrSNPCUTR2nE2UEZh7Y,35568
|
|
25
|
-
portacode/connection/handlers/system_handlers.py,sha256=
|
|
25
|
+
portacode/connection/handlers/system_handlers.py,sha256=nOlJ8kkiikdj4_Bz8IfYLLyy-X6LsP4FKoz6_GmQuP8,5706
|
|
26
26
|
portacode/connection/handlers/tab_factory.py,sha256=yn93h6GASjD1VpvW1oqpax3EpoT0r7r97zFXxML1wdA,16173
|
|
27
27
|
portacode/connection/handlers/terminal_handlers.py,sha256=HRwHW1GiqG1NtHVEqXHKaYkFfQEzCDDH6YIlHcb4XD8,11866
|
|
28
28
|
portacode/connection/handlers/project_state/README.md,sha256=trdd4ig6ungmwH5SpbSLfyxbL-QgPlGNU-_XrMEiXtw,10114
|
|
@@ -38,7 +38,7 @@ portacode/static/js/utils/ntp-clock.js,sha256=KMeHGT-IlUSlxVRZZ899z25dQCJh6EJbgX
|
|
|
38
38
|
portacode/utils/NTP_ARCHITECTURE.md,sha256=WkESTbz5SNAgdmDKk3DrHMhtYOPji_Kt3_a9arWdRig,3894
|
|
39
39
|
portacode/utils/__init__.py,sha256=NgBlWTuNJESfIYJzP_3adI1yJQJR0XJLRpSdVNaBAN0,33
|
|
40
40
|
portacode/utils/ntp_clock.py,sha256=6QJOVZr9VQuxIyJt9KNG4dR-nZ3bKNyipMxjqDWP89Y,5152
|
|
41
|
-
portacode-1.3.
|
|
41
|
+
portacode-1.3.37.dist-info/licenses/LICENSE,sha256=2FGbCnUDgRYuQTkB1O1dUUpu5CVAjK1j4_p6ack9Z54,1066
|
|
42
42
|
test_modules/README.md,sha256=Do_agkm9WhSzueXjRAkV_xEj6Emy5zB3N3VKY5Roce8,9274
|
|
43
43
|
test_modules/__init__.py,sha256=1LcbHodIHsB0g-g4NGjSn6AMuCoGbymvXPYLOb6Z7F0,53
|
|
44
44
|
test_modules/test_device_online.py,sha256=yiSyVaMwKAugqIX_ZIxmLXiOlmA_8IRXiUp12YmpB98,1653
|
|
@@ -63,8 +63,8 @@ testing_framework/core/playwright_manager.py,sha256=kWKmlxzftDY0ZWS891zlHu_Ctdw7
|
|
|
63
63
|
testing_framework/core/runner.py,sha256=j2QwNJmAxVBmJvcbVS7DgPJUKPNzqfLmt_4NNdaKmZU,19297
|
|
64
64
|
testing_framework/core/shared_cli_manager.py,sha256=BESSNtyQb7BOlaOvZmm04T8Uezjms4KCBs2MzTxvzYQ,8790
|
|
65
65
|
testing_framework/core/test_discovery.py,sha256=2FZ9fJ8Dp5dloA-fkgXoJ_gCMC_nYPBnA3Hs2xlagzM,4928
|
|
66
|
-
portacode-1.3.
|
|
67
|
-
portacode-1.3.
|
|
68
|
-
portacode-1.3.
|
|
69
|
-
portacode-1.3.
|
|
70
|
-
portacode-1.3.
|
|
66
|
+
portacode-1.3.37.dist-info/METADATA,sha256=sRpzOeUTy_7TvPzGWQqZGMF-khXlJ9IKBshPRH2UAOY,6989
|
|
67
|
+
portacode-1.3.37.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
68
|
+
portacode-1.3.37.dist-info/entry_points.txt,sha256=lLUUL-BM6_wwe44Xv0__5NQ1BnAz6jWjSMFvZdWW3zU,48
|
|
69
|
+
portacode-1.3.37.dist-info/top_level.txt,sha256=TGhTYUxfW8SyVZc_zGgzjzc24gGT7nSw8Qf73liVRKM,41
|
|
70
|
+
portacode-1.3.37.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|