mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-05 04:02:31 +02:00
142 lines
7.7 KiB
Markdown
142 lines
7.7 KiB
Markdown
# Жизненный цикл модуля
|
||||
|
|
|
|||
|
|
Как XC_VM обнаруживает, загружает, включает/отключает, устанавливает и распространяет модули во время выполнения. Чтобы создать модуль, смотрите [Разработка модуля](module-authoring.md); для его расширений смотрите [Точки расширения модуля](module-extension-points.md).
|
|||
|
|
|
|||
|
|
## Включение / выключение модулей
|
|||
|
|
|
|||
|
|
|
|||
|
|
Все обнаруженные модули загружаются по умолчанию. Используйте `src/config/modules.php` для переопределения состояния:
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
return [
|
|||
|
|
'my-module' => ['state' => 'disabled'], // preferred
|
|||
|
|
// or legacy boolean (still accepted):
|
|||
|
|
'my-module' => ['enabled' => false],
|
|||
|
|
];
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Доступные значения `state` (подкрепленные перечислением `ModuleState`):
|
|||
|
|
|
|||
|
|
|Ценность|Значение|
|
|||
|
|
| ----- | ------- |
|
|||
|
|
| `enabled` |Загрузка модуля (по умолчанию)|
|
|||
|
|
| `disabled` |Модуль обнаружен, но пропущен|
|
|||
|
|
| `installing` |Переходное состояние, заданное значением `ModuleManager` во время установки|
|
|||
|
|
| `failed` |Ошибка установки; модуль пропущен (не загружен)|
|
|||
|
|
|
|||
|
|
> **Панельная диагностика.** На странице **Модули** отображается желтый значок **⚠ Проблема зависимости** рядом со статусом модуля, если требуемая зависимость отсутствует или не включена (например, в `plex` указано `Enabled`, а в `watch` - `failed`). Во всплывающей подсказке к значку перечислены конкретные проблемы. Это поле `dependency_warnings` вычисляется с помощью `ModuleManager::listModules()`.
|
|||
|
|
|
|||
|
|
Чтобы переопределить класс, разрешенный для модуля:
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
return [
|
|||
|
|
'my-module' => ['class' => 'XcVm\\Module\\MyModuleV2\\MyModuleV2Module'],
|
|||
|
|
];
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`config/modules.php` содержит только переопределения. Пустой или отсутствующий файл означает, что все обнаруженные
|
|||
|
|
загружаются модули.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Как работает загрузка
|
|||
|
|
|
|||
|
|
|
|||
|
|
`ModuleLoader` выполняет эти действия при каждом запросе:
|
|||
|
|
|
|||
|
|
1. Сканирование `src/Modules/*/module.json`
|
|||
|
|
2. Применяет переопределения из `config/modules.php`
|
|||
|
|
3. Фильтры по окружающей среде (`main` / `lb` / `any`)
|
|||
|
|
4. Определяет порядок загрузки:
|
|||
|
|
- `pruneUnsatisfiableModules()` удаляет модули, требуемые зависимости которых недоступны (каскадно, с зарегистрированным предупреждением), чтобы загрузка никогда не прерывалась
|
|||
|
|
- Топологическая сортировка (DFS) по графу зависимостей
|
|||
|
|
- В пределах одной и той же группы зависимостей выполните сортировку по убыванию `priority`, затем по алфавиту
|
|||
|
|
- Выдает `ModuleCycleException` для циклов (подкласс `\RuntimeException`; циклические зависимости остаются фатальными)
|
|||
|
|
- Отсутствующие необязательные зависимости автоматически пропускаются
|
|||
|
|
5. Resolves class name: `my-module` → FQN `XcVm\Module\MyModule\MyModuleModule`
|
|||
|
|
(kebab-case → PascalCase; может быть переопределен с помощью клавиши `class` в конфигурации)
|
|||
|
|
6. Регистрирует автозагрузчик модуля PSR-4 (сопоставляет `XcVm\Module\<Name>` с каталогом модуля)
|
|||
|
|
7. Создает экземпляр класса module
|
|||
|
|
|
|||
|
|
В веб-контексте:
|
|||
|
|
|
|||
|
|
- `bootAll($container, $router)` → вызовы `boot()`, `registerRoutes()`, `registerNavbar()`,
|
|||
|
|
и подписывается на события для каждого загруженного модуля
|
|||
|
|
|
|||
|
|
В контексте командной строки:
|
|||
|
|
|
|||
|
|
- `registerAllCommands($registry)` → вызывает `registerCommands()` для каждого загруженного модуля
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Marketplace: установка через расширение C
|
|||
|
|
|
|||
|
|
|
|||
|
|
Модули с платформы устанавливаются через `ModuleManager::downloadFromPlatform()`:
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
$manager->downloadFromPlatform(slug: 'my-module', version: '1.2.0', apiKey: $key);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Под капотом:
|
|||
|
|
|
|||
|
|
1. `XC_VM::module_install($slug, $version, $apiKey)` — Расширение C загружает, расшифровывает и распаковывает файлы
|
|||
|
|
2. `installModule($slug)` — запускает `install()` в модуле
|
|||
|
|
3. `EventDispatcher::dispatch(new PackageInstalledEvent(...))` — отправляет событие
|
|||
|
|
4. `hotReload($slug, $path)` — загружает модуль в текущем запросе **без перезапуска PHP-FPM**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Изолированные подсистемы
|
|||
|
|
|
|||
|
|
|
|||
|
|
Модуль может быть полностью изолированной подсистемой со своей собственной точкой входа и начальной загрузкой
|
|||
|
|
(например, Ministra). Это **соглашение**, а не маркерный интерфейс — он остается
|
|||
|
|
обычный модуль `ModuleInterface`/`BaseModule`:
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
class MyModule extends BaseModule {
|
|||
|
|
|
|||
|
|
public function getName(): string {
|
|||
|
|
return 'my-module';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public function getVersion(): string {
|
|||
|
|
return '1.0.0';
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Изоляция означает, что подсистема работает через свою собственную общедоступную точку входа (например,
|
|||
|
|
`my-module/portal.php`, путь относительно `src/`, который обрабатывает свой собственный bootstrap)
|
|||
|
|
с отдельным путем начальной загрузки. Он использует общую инфраструктуру (базу данных, кэш, конфигурацию), но
|
|||
|
|
участвует ли **нет** в основных `Router`, `ModuleLoader::bootAll()` или
|
|||
|
|
`NavbarRegistry`. Реализации `boot()` и `registerRoutes()` обычно являются
|
|||
|
|
оставлено как унаследованное бездействие.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Composer обнаружение пакета
|
|||
|
|
|
|||
|
|
|
|||
|
|
Модули могут распространяться в виде Composer пакетов с `"type": "xcvm-module"`:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"name": "vendor/my-xcvm-module",
|
|||
|
|
"type": "xcvm-module",
|
|||
|
|
"extra": {
|
|||
|
|
"xcvm": {
|
|||
|
|
"module-path": "src"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`ModuleLoader` автоматически сканирует `vendor/composer/installed.json` (Composer 1 и 2
|
|||
|
|
форматирует) и обнаруживает все установленные пакеты `xcvm-module` вместе со встроенным
|
|||
|
|
каталог `src/Modules/`. Пакеты дедуплицируются — модуль как в `modules/`, так и в
|
|||
|
|
`vendor/` загружается только один раз.
|
|||
|
|
|
|||
|
|
---
|