mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-10-10 00:08:11 +03:00
56 lines
5.3 KiB
Markdown
56 lines
5.3 KiB
Markdown
# Application composition guidance
|
|
|
|
Inherit the [nearest parent guide](../AGENTS.md). Composition owns partial startup acquisitions and
|
|
dependency-ordered teardown. Outer supervision interprets application exit; inner cleanup owns its resources.
|
|
Read `Furious/Application/DesktopApplication.py` with `tests/test_architecture_refactors.py`; paths are
|
|
relative to this source tree's root.
|
|
|
|
- `Furious.__main__` and `AppMainProcess` own the outer process/crash boundary; `DesktopApplication` owns the inner Qt
|
|
composition. Keep those responsibilities separate and preserve semantic exit codes and original failure context.
|
|
- Plugin, storage, and UI initialization follows singleton election; the Qt application and its initial resource
|
|
owners already exist during election. Plugins are available before repository restoration interprets persisted
|
|
profiles. Register cleanup as each acquisition succeeds, including election-failure paths, and preserve these
|
|
dependencies when changing stage order.
|
|
- Partial startup, normal exit, signals, and event-loop failure converge on one reverse-order cleanup path.
|
|
`aboutToQuit` and the event-loop `finally` may both reach it; repeated entry must not repeat registered stages.
|
|
One callback failure does not skip later stages, but the stack consumes that callback and does not retry it.
|
|
Its successful `close()` return means this invocation ran the stack, not that every resource was released.
|
|
Service-level retry/retention obligations must be satisfied before the owner disappears. `exit()` requests Qt
|
|
termination; action/window/session handlers do not run cleanup directly.
|
|
- A stage that fails before its cleanup callback is registered must release its own partial acquisitions. The outer
|
|
cleanup stack releases completed stages; it cannot discover half-built controllers, UI, logging handlers, or
|
|
native listeners. Keep each successful sub-acquisition reachable by the stage's failure cleanup before beginning
|
|
the next fallible constructor; assigning several constructed owners together does not provide this guarantee.
|
|
Restore logging configuration as well as closing handlers. A failed controller shutdown currently retains that
|
|
controller, but the consumed application cleanup stage does not automatically retry it. Preserve the owner and
|
|
report incomplete cleanup; any retry policy must specify who invokes it before dependent owners are dismantled.
|
|
For resource-owning controllers, schedule native deletion only after successful shutdown. UI deletion and
|
|
workflow draining are separate stages; trace both rather than assuming `deleteLater()` waits for resources.
|
|
Review cooperative pool drains separately from the cleanup stack's ordering guarantees. The application pool's
|
|
timed wait logs unfinished work, whereas subscription preparation waits synchronously after its diagnostic timeout.
|
|
Neither policy can be inferred from reverse cleanup order or from the name of a shutdown method.
|
|
- Singleton election serializes cooperating candidates, re-probes after waiting, recovers only a confirmed stale
|
|
endpoint, and fails closed when ownership is uncertain, including privilege handoff. A successful Windows
|
|
local-server listen alone does not establish exclusivity; command delivery and endpoint ownership are separate
|
|
observations.
|
|
A forwarded or unresolved launch must unwind its initial owners without restoring a connection or bootstrapping
|
|
ordinary UI. Constructing a Qt application for election or fallback reporting does not grant primary ownership.
|
|
- Each singleton IPC connection creates a short-lived socket sender. Use weak named dispatch with sender forwarding
|
|
to the application; repeatedly connecting a compiled application bound method can grow Nuitka's protection list
|
|
even after the native sockets die. The server owns sockets through their one-command completion/disconnection.
|
|
Verify completed socket destruction and repeated callback registrations independently; a persistent application
|
|
receiver does not make an unbounded sequence of compiled registrations safe.
|
|
- Native session callbacks cross to the GUI thread before touching Qt-owned state. Tray, dock, System Proxy daemon,
|
|
Flatpak/AppImage, and no-tray behavior are explicit platform capabilities.
|
|
- The application owns the top-level window/tray wrappers; `MainWindow` owns the persistent page tree. Cleanup order
|
|
follows dependencies: consumers stop while the plugins, repositories, and Qt objects they need are still valid.
|
|
A registered cleanup callback establishes responsibility, not proof that its menus, sockets, snapshots, or workers
|
|
were released. Verify partial composition as well as a fully constructed application.
|
|
Tray actions have an explicit QObject owner; the borrowed top-level tray menu needs native deletion independent
|
|
of the tray wrapper's Python lifetime. Use the shared Qt ownership rules and the lifetime probe for this boundary.
|
|
- Verify each acquisition failure, reverse/repeated cleanup, singleton races/commands, queued session shutdown,
|
|
tray-present/absent close policy, restored connection, and exact child/thread-pool ownership with host effects
|
|
mocked. Start with `tests/test_architecture_refactors.py`, `tests/test_application_process.py`, and
|
|
`tests/test_main_window_geometry.py`; use their partial-startup cases to challenge this guide when composition
|
|
changes.
|