## Summary epic r04 - begin refactor ## Change Type - [x] Cowork feature - [ ] Bug fix - [ ] Core AI contribution - [ ] Test / hardening - [ ] Performance - [ ] Documentation ## Related Work Cowork Task: Core Repo: http://34.143.229.138/gitea-admin/fsg-ai-core-assets Core AI Issue: Core Task: Related PR: ## Scope What is intentionally included? What is intentionally NOT included? ## Validation - [ ] Unit tests - [ ] Integration tests - [ ] Manual verification - [ ] Regression check Commands / evidence: ## Security Impact Permission / credential / network / customer data impact: ## Compatibility - [ ] No breaking change - [ ] Breaking change documented ## Reviewer Notes Anything Cowork reviewers should pay attention to. --------- Co-authored-by: Anh Tran Nguyen Minh <anhtnm1@fpt.com> Co-authored-by: Huong Le Thi Thien <huongltt35@fpt.com> Co-authored-by: Nam Pham Dinh Thanh <nampdt@fpt.com> Co-authored-by: Vu Dam Tuan <vudt15@fpt.com> Co-authored-by: Hiep Ha Van <hiephv3@fpt.com> Co-authored-by: Lam Hoang Van <lamhv7@fpt.com> Reviewed-on: #7 Co-authored-by: Duy Le Huu <duylh19@fpt.com>
This commit was merged in pull request #7.
This commit is contained in:
@@ -29,6 +29,7 @@ _ACTIVE_PIDS: set[int] = set()
|
||||
|
||||
|
||||
def active_pids() -> List[int]:
|
||||
"""Pid của các tiến trình con đang chạy — dùng để dọn sạch khi thoát app."""
|
||||
with _active_pids_lock:
|
||||
return sorted(_ACTIVE_PIDS)
|
||||
|
||||
@@ -142,6 +143,11 @@ def _run_cancellable_body(
|
||||
proc: "subprocess.Popen", cancel: CancelFn, timeout: Optional[float],
|
||||
on_output: Optional[Callable[[str], None]], limits: Optional[Dict[str, float]],
|
||||
) -> Tuple[Optional[int], str, bool, bool, bool]:
|
||||
"""Chạy một tiến trình con có thể huỷ giữa chừng, có hạn giờ và có giới hạn tài nguyên.
|
||||
|
||||
Trên Windows gắn tiến trình vào một Job Object để khi giết là giết cả cây
|
||||
tiến trình con — giết mỗi tiến trình cha sẽ để lại đám con mồ côi.
|
||||
"""
|
||||
job_handle = None
|
||||
if sys.platform == "win32":
|
||||
from .win_job import assign_process, create_job_object
|
||||
@@ -158,6 +164,11 @@ def _run_cancellable_body(
|
||||
collected: Dict[str, list] = {"out": [], "err": []}
|
||||
|
||||
def _read_stream(stream, key: str) -> None:
|
||||
"""Đọc một luồng đầu ra theo từng dòng ở luồng riêng.
|
||||
|
||||
Phải đọc song song stdout và stderr: đọc lần lượt sẽ kẹt khi tiến trình con
|
||||
làm đầy bộ đệm của luồng còn lại.
|
||||
"""
|
||||
try:
|
||||
for line in iter(stream.readline, ""):
|
||||
collected[key].append(line)
|
||||
@@ -239,6 +250,7 @@ def network_blocked_env(base_env: Optional[Dict[str, str]] = None) -> Dict[str,
|
||||
|
||||
def _can_pip() -> bool:
|
||||
# A PyInstaller/py2exe build has no usable pip; don't attempt installs there.
|
||||
"""Bản đóng gói (PyInstaller) không có pip dùng được — đừng thử cài gì ở đó."""
|
||||
return not getattr(sys, "frozen", False)
|
||||
|
||||
|
||||
@@ -267,6 +279,7 @@ def ensure_module(module: str, package: str | None = None):
|
||||
|
||||
|
||||
def venv_python_path(venv_dir: Path) -> Path:
|
||||
"""Đường dẫn tới ``python`` trong một virtualenv, khác nhau giữa Windows và POSIX."""
|
||||
return venv_dir / ("Scripts/python.exe" if sys.platform == "win32" else "bin/python")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user