Files
XC_VM/docs/ru/guides/process-management.md
T
Divarion-D 76844fef11 docs: restructure, fix PSR-4 drift, and unify en/ru
Overhaul the Docsify documentation (English + Russian) so it matches the current
codebase and follows one consistent pattern.

Content accuracy (post-migration):
- Rewrite development/autoloader.md to PSR-4 / Composer (the old XC_Autoloader
  scanner, igbinary tmp/cache/autoload_map and registerDirectories are gone).
- PascalCase every source path (src/core -> src/Core, domain/Stream, cli/Commands,
  public/Controllers, Infrastructure/Redis, ...) across all docs.
- Replace the removed autoload.php references with vendor/autoload.php
  (build_system, bootstrap-contexts, error-handling, modules).
- ssl-generation: note that the installer now auto-generates a unique self-signed
  certificate before Nginx starts.

Common pattern (Clean & uniform):
- Strip emoji from headings; remove the in-page Navigation blocks (the Docsify
  sidebar already provides navigation).
- One H1 + intro per doc; uniform "Related files" / "Связанные файлы" section,
  added to the code-centric docs that lacked it.

Structure:
- Remove the empty stray docs/api/; move updates_checklist.md into builds/;
  link the previously-orphaned ucs-integration.md.
- Regroup the sidebars (split the oversized guides group into Developer Guides /
  Security & Access / Integrations; fold builds into Build & Release).

Augment:
- dev-workflow: Local Setup (make dev-tools) + Quality Checks (phpstan, cs, gates).
- build_system: Composer Dependencies section (committed prod-only vendor,
  committed lock, dev tools via composer install, no build-time vendor step).

en/ru parity:
- Apply the same structure, fixes and pattern to docs/ru/ (translated), including
  a new Russian ucs-integration.md. The en and ru file sets are now identical.
2026-06-26 15:56:15 +03:00

6.0 KiB
Raw Blame History

Паттерны управления процессами

ProcessManager централизует операции с процессами Linux: проверку активности, завершение и захват cron-блокировок. Заменяет разрозненные вызовы posix_kill(), shell_exec('ps ...') и file_exists('/proc/PID').


Базовые операции

Проверка активности процесса

// Проверить, жив ли процесс
ProcessManager::isRunning(int $pid, ?string $exe = null): bool
  • Без $exe — только проверяет наличие /proc/{pid}
  • С $exe — дополнительно проверяет имя исполняемого файла через /proc/{pid}/exe
// Примеры
ProcessManager::isRunning(1234);              // процесс жив?
ProcessManager::isRunning(1234, 'ffmpeg');    // это ffmpeg?
ProcessManager::isRunning(1234, PHP_BIN);     // это PHP?

Именованный процесс

Для процессов, которые устанавливают заголовок через cli_set_process_title() в формате NAME[ID]:

ProcessManager::isNamedProcessRunning(
    int $pid,
    string $processName,  // 'XC_VM', 'Thumbnail', 'TVArchive'
    int|string $identifier, // stream ID
    ?string $exe = null   // ожидаемый исполняемый (по умолч.: PHP_BIN)
): bool
// Проверить, запущен ли PHP-процесс "XC_VM[42]" с PID 5678
ProcessManager::isNamedProcessRunning(5678, 'XC_VM', 42);

Читает /proc/{pid}/cmdline и сравнивает с "NAME[ID]".

Стриминговый процесс

Специализированная проверка для FFmpeg/PHP стриминговых процессов:

ProcessManager::isStreamRunning(int $pid, int $streamId): bool

Логика:

  • Если исполняемый файл — ffmpeg: проверяет cmdline на наличие /{streamId}_.m3u8 или /{streamId}_%d.ts
  • Если исполняемый файл — php: возвращает true (PHP-стримеры не имеют уникальных аргументов)

PID-файлы

// Проверить процесс по PID-файлу
ProcessManager::checkPidFile(string $pidFile, string $searchString): bool

// Проверить, содержит ли cmdline процесса заданную строку
ProcessManager::matchesCmdline(int $pid, string $search): bool
// Пример cron-задачи
if (ProcessManager::checkPidFile('/tmp/my_cron.pid', 'my_cron_script')) {
    // процесс уже запущен
    exit(0);
}

Завершение процессов

ProcessManager::kill(int $pid, int $signal = SIGKILL): bool

По умолчанию — SIGKILL (немедленное завершение). Для мягкого завершения:

ProcessManager::kill($pid, SIGTERM);  // дать время на завершение
ProcessManager::kill($pid, SIGKILL);  // принудительно

Cron-блокировки

Предотвращает параллельный запуск одной и той же cron-задачи.

ProcessManager::acquireCronLock(string $pidFile, int $maxAge = 1800): void
  • Если PID-файл существует и процесс ещё жив — завершает текущий скрипт (exit(0))
  • Если PID-файл устарел (старше $maxAge секунд) — удаляет и создаёт новый
  • Если блокировка захвачена — регистрирует register_shutdown_function для автоматической очистки PID-файла
// Типичное использование в cron-задаче
ProcessManager::acquireCronLock('/tmp/xc_vm/cron_streams.pid', 1800);

// ... дальнейшая работа ...
// PID-файл удаляется автоматически при завершении скрипта

Кеш проверок /proc

isRunning() кеширует результаты проверок /proc/{pid} на 1 секунду ($cacheTtl = 1.0). Это снижает нагрузку при множественных проверках одного PID в рамках одного запроса.

Для принудительного сброса кеша перед критичной проверкой:

clearstatcache(true);
ProcessManager::isNamedProcessRunning($pid, 'XC_VM', $streamId);

Именование процессов

XC_VM использует соглашение NAME[ID] для именования PHP-процессов:

Имя процесса Описание
XC_VM[{id}] Основной стриминговый процесс
Thumbnail[{id}] Генерация превью
TVArchive[{id}] TV-архивирование

Эти имена устанавливаются через cli_set_process_title() в CLI-контексте. Подробнее о CLI-контексте — в Контексты Bootstrap.


Связанные файлы

Файл Назначение
src/Core/Process/ProcessManager.php Основной класс управления процессами
src/Core/Process/Multithread.php Многопоточное выполнение
src/Core/Process/Thread.php Обёртка потока
src/bootstrap.php CONTEXT_CLI устанавливает имя процесса