Рефакторинг network-runtime: выделены ProtocolRuntimeCore, DeviceRuntimeService и OutgoingMessagePipelineService
This commit is contained in:
@@ -7,12 +7,14 @@
|
||||
Приложение сейчас устроено как layered + service-oriented архитектура:
|
||||
- UI: `MainActivity` + Compose-экраны + ViewModel.
|
||||
- DI: Hilt (`@HiltAndroidApp`, `@AndroidEntryPoint`, модули в `di/AppContainer.kt`).
|
||||
- Runtime orchestration: `ProtocolManager`, `CallManager`, `TransportManager`, `UpdateManager`.
|
||||
- Runtime orchestration: `ProtocolRuntime` -> `ProtocolRuntimeCore` (+ compatibility facade `ProtocolManager`), `CallManager`, `TransportManager`, `UpdateManager`.
|
||||
- Session/Identity runtime state: `SessionStore`, `SessionReducer`, `IdentityStore`.
|
||||
- Data: `MessageRepository`, `GroupRepository`, `AccountManager`, `PreferencesManager`.
|
||||
- Persistence: Room (`RosettaDatabase`) + DataStore/SharedPreferences.
|
||||
|
||||
`ProtocolManager` остается крупным runtime orchestrator-объектом, но критичные зоны уже вынесены в отдельные сервисы.
|
||||
Основная runtime-логика сети вынесена в instance-класс `ProtocolRuntimeCore`.
|
||||
`ProtocolManager` сохранен как тонкий compatibility facade.
|
||||
DI-вход в network core идет через `ProtocolRuntime` (Hilt singleton).
|
||||
|
||||
---
|
||||
|
||||
@@ -29,11 +31,12 @@ flowchart TB
|
||||
|
||||
subgraph DI["Hilt Singleton Graph"]
|
||||
D1["ProtocolGateway"]
|
||||
D1A["ProtocolRuntime"]
|
||||
D2["SessionCoordinator"]
|
||||
D3["IdentityGateway"]
|
||||
D4["AccountManager / PreferencesManager"]
|
||||
D5["MessageRepository / GroupRepository"]
|
||||
D6["UiEntryPoint + UiDependencyAccess"]
|
||||
D6["UiEntryPoint + EntryPointAccessors"]
|
||||
end
|
||||
|
||||
subgraph SESSION["Session / Identity Runtime"]
|
||||
@@ -44,7 +47,9 @@ flowchart TB
|
||||
end
|
||||
|
||||
subgraph NET["Network Runtime"]
|
||||
N1["ProtocolManager"]
|
||||
N0["ProtocolRuntime"]
|
||||
N1["ProtocolRuntimeCore"]
|
||||
N1A["ProtocolManager (compat facade)"]
|
||||
N2["Protocol"]
|
||||
N3["PacketSubscriptionRegistry"]
|
||||
N4["ReadyPacketGate"]
|
||||
@@ -60,6 +65,9 @@ flowchart TB
|
||||
DI --> SESSION
|
||||
DI --> NET
|
||||
DI --> DATA
|
||||
D1 --> D1A
|
||||
D1A --> N1
|
||||
N1A --> N1
|
||||
SESSION --> NET
|
||||
DATA --> NET
|
||||
DATA --> R3
|
||||
@@ -75,11 +83,26 @@ flowchart TB
|
||||
- Entry points уровня Android-компонентов: `MainActivity`, `IncomingCallActivity`, `CallForegroundService`, `RosettaFirebaseMessagingService`.
|
||||
- Основные модули:
|
||||
- `AppDataModule`: `AccountManager`, `PreferencesManager`.
|
||||
- `AppGatewayModule`: биндинги `ProtocolGateway`, `SessionCoordinator`, `IdentityGateway`.
|
||||
- `AppGatewayModule`: биндинги `ProtocolGateway`, `SessionCoordinator`, `IdentityGateway`, `ProtocolClient`.
|
||||
- `ProtocolGatewayImpl` и `ProtocolClientImpl` делегируют в `ProtocolRuntime`, а не напрямую в UI-слой.
|
||||
|
||||
### 3.2 UI bridge для не-Hilt классов
|
||||
Часть UI/VM пока получает зависимости через `UiDependencyAccess` -> `UiEntryPoint`.
|
||||
Это transitional-слой, чтобы не тащить singleton `getInstance(...)` в UI и постепенно перейти на чистый constructor injection.
|
||||
### 3.2 UI bridge для composable-слоя
|
||||
UI-композаблы получают зависимости через `UiEntryPoint` + `EntryPointAccessors.fromApplication(...)`.
|
||||
`UiDependencyAccess.get(...)` из `ui/*` удален (DoD: 0 вхождений).
|
||||
|
||||
Для non-Hilt `object`-ов (`CallManager`, `TransportManager`, `UpdateManager`, utils)
|
||||
используется `ProtocolRuntimeAccess` + `ProtocolRuntimePort`:
|
||||
- runtime ставится в `RosettaApplication` через `ProtocolRuntimeAccess.install(protocolRuntime)`;
|
||||
- доступ до install запрещен (fail-fast), чтобы не было тихого отката в `ProtocolManager`.
|
||||
|
||||
### 3.3 Разрыв DI-cycle (Hilt)
|
||||
После перехода на `ProtocolRuntime` был закрыт цикл зависимостей:
|
||||
`MessageRepository -> ProtocolClient -> ProtocolRuntime -> MessageRepository`.
|
||||
|
||||
Текущее решение:
|
||||
- `ProtocolClientImpl` получает `Provider<ProtocolRuntime>` (ленивая резолюция).
|
||||
- `ProtocolRuntime` остается singleton-композицией для `MessageRepository/GroupRepository/AccountManager`.
|
||||
- На `assembleDebug/assembleRelease` больше нет `Dagger/DependencyCycle`.
|
||||
|
||||
---
|
||||
|
||||
@@ -129,21 +152,36 @@ stateDiagram-v2
|
||||
|
||||
## 5. Network orchestration после декомпозиции
|
||||
|
||||
`ProtocolManager` теперь делегирует отдельные зоны ответственности:
|
||||
`ProtocolRuntime` — DI-фасад runtime слоя.
|
||||
`ProtocolRuntimeCore` содержит runtime state machine и делегирует отдельные зоны ответственности:
|
||||
- `ConnectionOrchestrator`: connect/reconnect/authenticate + network-aware поведение.
|
||||
- `BootstrapCoordinator`: пересчет lifecycle (`AUTHENTICATED`/`BOOTSTRAPPING`/`READY`) и работа с `ReadyPacketGate`.
|
||||
- `SyncCoordinator`: sync state machine (request/timeout, BATCH_START/BATCH_END/NOT_NEEDED, foreground/manual sync).
|
||||
- `PresenceTypingService`: in-memory typing presence с TTL и snapshot `StateFlow`.
|
||||
- `PacketRouter`: user/search cache + resolve/search continuation routing.
|
||||
- `OwnProfileSyncService`: применение собственного профиля из search и синхронизация `IdentityStore`.
|
||||
- `RetryQueueService`: retry очереди отправки `PacketMessage`.
|
||||
- `AuthBootstrapCoordinator`: session-aware post-auth bootstrap (transport/update/profile/sync/push).
|
||||
- `NetworkReconnectWatcher`: единый watcher ожидания сети и fast-reconnect триггеры.
|
||||
- `DeviceVerificationService`: состояние списка устройств + pending verification + resolve packets.
|
||||
- `DeviceRuntimeService`: device-id/handshake device + device verification orchestration.
|
||||
- `CallSignalBridge`: call/webrtc/ice signal send+subscribe bridge.
|
||||
- `PacketSubscriptionRegistry`: централизованные подписки на пакеты и fan-out.
|
||||
- `OutgoingMessagePipelineService`: отправка `PacketMessage` с retry/error policy.
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
PM["ProtocolManager"] --> CO["ConnectionOrchestrator"]
|
||||
PM["ProtocolRuntimeCore"] --> CO["ConnectionOrchestrator"]
|
||||
PM --> BC["BootstrapCoordinator"]
|
||||
PM --> SC["SyncCoordinator"]
|
||||
PM --> PT["PresenceTypingService"]
|
||||
PM --> PR["PacketRouter"]
|
||||
PM --> OPS["OwnProfileSyncService"]
|
||||
PM --> RQ["RetryQueueService"]
|
||||
PM --> ABC["AuthBootstrapCoordinator"]
|
||||
PM --> NRW["NetworkReconnectWatcher"]
|
||||
PM --> DVS["DeviceVerificationService"]
|
||||
PM --> CSB["CallSignalBridge"]
|
||||
PM --> PSR["PacketSubscriptionRegistry"]
|
||||
PM --> SUP["ProtocolConnectionSupervisor"]
|
||||
PM --> RPG["ReadyPacketGate"]
|
||||
@@ -163,7 +201,7 @@ flowchart TB
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Feature as Feature/Service
|
||||
participant PM as ProtocolManager
|
||||
participant PM as ProtocolRuntimeCore
|
||||
participant REG as PacketSubscriptionRegistry
|
||||
participant P as Protocol
|
||||
|
||||
@@ -189,14 +227,14 @@ sequenceDiagram
|
||||
1. ViewModel готовит command и шифрованный payload.
|
||||
2. UseCase собирает `PacketMessage`.
|
||||
3. UseCase вызывает `protocolGateway.sendMessageWithRetry(packet)`.
|
||||
4. `ProtocolManager` регистрирует пакет в `RetryQueueService` и отправляет в сеть.
|
||||
4. `ProtocolRuntimeCore` регистрирует пакет в `RetryQueueService` и отправляет в сеть.
|
||||
5. Если lifecycle еще не `READY`, пакет попадает в `ReadyPacketGate` и flush после `READY`.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
VM["ChatViewModel"] --> UC["Send*UseCase"]
|
||||
UC --> GW["ProtocolGateway.sendMessageWithRetry"]
|
||||
GW --> PM["ProtocolManager"]
|
||||
GW --> PM["ProtocolRuntimeCore"]
|
||||
PM --> RQ["RetryQueueService"]
|
||||
PM --> RG["ReadyPacketGate"]
|
||||
PM --> P["Protocol.sendPacket"]
|
||||
@@ -212,7 +250,7 @@ sequenceDiagram
|
||||
participant SC as SessionCoordinatorImpl
|
||||
participant SS as SessionStore
|
||||
participant PG as ProtocolGateway
|
||||
participant PM as ProtocolManager
|
||||
participant PM as ProtocolRuntimeCore
|
||||
participant AM as AccountManager
|
||||
|
||||
UI->>SC: bootstrapAuthenticatedSession(account, reason)
|
||||
@@ -235,7 +273,7 @@ sequenceDiagram
|
||||
|
||||
## 9. Состояния соединения (network lifecycle)
|
||||
|
||||
`ProtocolManager.connectionLifecycleState`:
|
||||
`ProtocolRuntimeCore.connectionLifecycleState`:
|
||||
- `DISCONNECTED`
|
||||
- `CONNECTING`
|
||||
- `HANDSHAKING`
|
||||
@@ -263,6 +301,10 @@ stateDiagram-v2
|
||||
|
||||
- `app/src/main/java/com/rosetta/messenger/di/AppContainer.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/di/UiEntryPoint.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/ProtocolRuntime.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/ProtocolRuntimeCore.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/ProtocolClient.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/ProtocolRuntimeAccess.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/session/AppSessionCoordinator.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/session/SessionStore.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/session/SessionReducer.kt`
|
||||
@@ -275,6 +317,14 @@ stateDiagram-v2
|
||||
- `app/src/main/java/com/rosetta/messenger/network/ReadyPacketGate.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/ConnectionOrchestrator.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/BootstrapCoordinator.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/SyncCoordinator.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/PresenceTypingService.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/AuthBootstrapCoordinator.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/NetworkReconnectWatcher.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/DeviceVerificationService.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/DeviceRuntimeService.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/CallSignalBridge.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/OutgoingMessagePipelineService.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/PacketRouter.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/OwnProfileSyncService.kt`
|
||||
- `app/src/main/java/com/rosetta/messenger/network/connection/RetryQueueService.kt`
|
||||
@@ -286,6 +336,7 @@ stateDiagram-v2
|
||||
|
||||
## 11. Что осталось как технический долг
|
||||
|
||||
- `ProtocolManager` все еще содержит много cross-cutting логики и требует дальнейшей декомпозиции.
|
||||
- Не весь UI перешел на constructor injection (`UiDependencyAccess` пока нужен для части ViewModel).
|
||||
- Часть data-слоя напрямую знает о network singleton (`ProtocolManager`) и требует окончательного разрыва через интерфейсы.
|
||||
- `ProtocolRuntimeCore` все еще содержит много cross-cutting логики и требует дальнейшей декомпозиции.
|
||||
- UI больше не использует `UiDependencyAccess.get(...)`, но часть экранов все еще берет зависимости через `UiEntryPoint` (следующий шаг: передача зависимостей параметрами/через VM).
|
||||
- DI-адаптеры (`ProtocolGatewayImpl`, `ProtocolClientImpl`) переведены на `ProtocolRuntime`, dependency-cycle закрыт через `Provider<ProtocolRuntime>`.
|
||||
- Следующий шаг по network core: продолжить декомпозицию `ProtocolRuntimeCore` (например: `ProtocolLifecycleLogger`, `AuthRestoreService`, `ProtocolTraceService`) и сократить фасад `ProtocolManager` до полного legacy-режима.
|
||||
|
||||
Reference in New Issue
Block a user