mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-10-13 01:38:33 +03:00
Clarify asynchronous cleanup ownership
Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
@@ -17,8 +17,11 @@ relative to this source tree's root.
|
||||
`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.
|
||||
Service-level retry/retention obligations must be satisfied before the owner disappears. `exit()` first requests
|
||||
controller shutdown while Qt delivery is still active, then requests Qt termination after successful connection
|
||||
cleanup. Action/window/session handlers do not run the application cleanup stack directly. Pending or refused
|
||||
quit must keep the main window usable; the application retains controllers whose shutdown has not completed.
|
||||
`tests/test_architecture_refactors.py` exercises the real quit/event-loop boundary alongside cleanup ordering.
|
||||
- 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
|
||||
|
||||
@@ -61,6 +61,10 @@ source tree's root.
|
||||
new acquisition while they remain. Final controller shutdown surfaces unresolved cleanup and preserves the
|
||||
next-start preference. Check these outcomes independently in `tests/test_controllers.py` and
|
||||
`tests/test_runtime_lifecycle.py`.
|
||||
Pending asynchronous cleanup stays `Disconnecting`, with runtime ownership in the service. Reconnect waits for
|
||||
successful release; a genuine cleanup failure returns to usable UI without admitting replacement resources.
|
||||
Shutdown publishes its result only after this stop operation finishes and preserves the startup preference.
|
||||
`tests/test_sing_tun.py` covers delayed authorization, cancellation, reconnect and shutdown with real Qt delivery.
|
||||
- System Proxy configuration is best effort. Its helper logs host failures; an explicit False return does not roll
|
||||
back an otherwise usable committed runtime or prevent Connected. Preserve exception-path recovery separately.
|
||||
Exercise actual helper results with mocked OS boundaries; Connected does not guarantee the OS proxy was applied.
|
||||
|
||||
@@ -57,6 +57,12 @@ relative to this source tree's root.
|
||||
in `tests/test_sing_tun.py` cover startup cancellation, validated status with binding-provided failure reasons,
|
||||
and cleanup refusal/retry. Privileged platform smoke tests remain separate from harmless source/compiled
|
||||
lifetime checks.
|
||||
On Linux the connection also owns an authorized host helper. Monitor its unexpected exit alongside the native
|
||||
child and publish once through the same runtime route; publication does not establish that the child was reaped.
|
||||
Pending Linux preparation/restoration sets `cleanupPending`; preserve IPC, timers and the host owner until that
|
||||
work completes. Poll host workers without blocking Qt on authorization. Native-child stop remains bounded and
|
||||
in its constructing Qt thread; do not move timer disposal into the host worker. Worker completion alone does not
|
||||
establish that its thread and helper were reaped; finish their release before clearing pending status.
|
||||
Binding-provided failure text is diagnostic input, not a stable enumerated protocol: preserve useful reasons rather
|
||||
than accepting only exact known strings. Changing binding versions requires coordinated model validation,
|
||||
distribution metadata/native-library inclusion, and workflow API checks; a successful import does not exercise TUN.
|
||||
|
||||
@@ -53,6 +53,12 @@ Read `Furious/Frozenlib/AppSettings.py` with `tests/test_frozenlib.py`; paths ar
|
||||
managed routing state. The service holds one helper per attempt and supplies its cancellation event; this module
|
||||
neither imports Service nor starts work during import. `tests/test_sing_tun_linux_host.py` covers the helper
|
||||
boundary; `tests/test_sing_tun.py` covers its use by the service, with privileged Linux smoke testing separate.
|
||||
Batch Linux setup and DNS into one fixed script. Keep that authorized helper until forwarding stops; closing its
|
||||
stdin runs its exact cleanup, including on parent exit. It accepts no executable commands from the application.
|
||||
Record successful rule additions in the helper for partial rollback. Kernel JSON read-back is a verification and
|
||||
recovery boundary, not the source of normal teardown commands; its field spellings differ from CLI selectors.
|
||||
PolicyKit authorization deliberately has no deadline, matching tun2socks. Keep it distinct from bounded host
|
||||
reads and explicit cancellation/reaping waits; elapsed time alone must not expire a pending password request.
|
||||
- Windows proxy calls, Linux desktop settings/host bridging, and macOS network-service operations are distinct
|
||||
paths. Application tun2socks host routing differs from backend-native TUN; preserve privilege, DNS restoration,
|
||||
and managed route cleanup for the selected path. Some helpers block synchronously and need caller-level
|
||||
|
||||
@@ -46,6 +46,10 @@ Read `Furious/Interface/Runtime.py` with `tests/test_interface.py`; paths are re
|
||||
cleanup remains observable to its owner and report violations separately from the required contract. Do not
|
||||
impose a Boolean release convention on `CoreRuntime.stop()` or `dispose()` merely because the service lease
|
||||
returns a Boolean: the lease combines exceptions and passive liveness into its own release outcome.
|
||||
`cleanupPending` separately reports asynchronous resource release. While true, callers retain the runtime and
|
||||
poll stop/dispose from their owning thread; pending work is not a failed stop or a disposed runtime. False alone
|
||||
is not release proof: exceptions and actual resource/liveness checks still apply. The default is false for
|
||||
synchronous implementations; sing-tun's Linux restoration and the lease tests anchor the deferred case.
|
||||
- Verify cheap/import-independent contracts plus representative runtime, storage, editor, application-exit,
|
||||
encoding, and configuration implementations. Update this guide when a contract intentionally changes, together
|
||||
with all implementers and compatibility tests. Start with `tests/test_interface.py` and
|
||||
|
||||
@@ -58,11 +58,19 @@ source tree's root.
|
||||
- For sing-tun, resolve automatic and manual remote exclusions before applying host routing, then require
|
||||
native readiness and checked DNS application before commit. `SingTUNHostPlan` owns only its assigned identifiers
|
||||
and DNS snapshots, independently of legacy `SystemRoutingTable.managedRoutes`; refuse ambiguous recovery and
|
||||
retain ownership for retry. Host preparation/DNS commands run in its owned worker, while synchronous compatibility
|
||||
startup and bounded cleanup joins remain explicit responsiveness limits. Delegate Linux host operations to
|
||||
retain ownership for retry. Host preparation/DNS commands run in its owned worker. Linux authorization and its
|
||||
startup observer have no deadline; other readiness checks keep their own deadlines. Linux restoration is polled
|
||||
through the manager's stop operation rather than joined on Qt's thread. Synchronous startup remains a compatibility
|
||||
path; synchronous stop callers report incomplete release while asynchronous cleanup is pending.
|
||||
Delegate Linux host operations to
|
||||
`Frozenlib/SingTUNRouting.py`; the service retains attempt orchestration, its worker and the helper's lifetime.
|
||||
Linux uses an attempt-owned PolicyKit
|
||||
helper to create a persistent TUN owned by the calling user and configure routes/DNS; the unprivileged binding
|
||||
Linux uses one attempt-owned PolicyKit
|
||||
helper to create a persistent TUN owned by the calling user and configure routes/DNS in one authorization. Keep
|
||||
the helper through forwarding and close its control pipe after the native child is reaped, so ordinary disconnect
|
||||
does not request another password. Unexpected helper exit fails the connection through its runtime owner.
|
||||
If the Linux forwarding child cannot be reaped, retain its helper and per-link DNS; report restoration as deferred
|
||||
instead of claiming DNS was restored while the helper remains active.
|
||||
The unprivileged binding
|
||||
receives external-configuration options only in its runtime copy. Windows/macOS retain native auto-routing.
|
||||
Retain unfinished helpers and their cancellation scripts until they are reaped; cancellation does not grant
|
||||
permission to forget an elevated process. Delete only an interface whose captured index matches, and
|
||||
@@ -78,6 +86,10 @@ source tree's root.
|
||||
retry and refuses new startup while release remains incomplete. A failed attempt transfers unreleased leases
|
||||
back to that durable owner; deleting the attempt must not abandon them. Independent DNS cleanup still runs.
|
||||
Verify runtime liveness and actual handle/thread release separately from the lease's logical state.
|
||||
Pending cleanup is observed through the runtime contract and is not logged as failure. Stop failures retain the
|
||||
runtime without immediately retrying via dispose, which could open another authorization request. The stop
|
||||
operation owns its Qt timer; destroyed observers leave their leases with the manager. Retire stop admission before
|
||||
terminal signals, preserve other runtimes' independent cleanup, and reject new startup until release completes.
|
||||
Native startup-operation destruction cancels child observers and rolls back an uncommitted attempt before child
|
||||
deletion. Terminal observers may destroy the operation synchronously; retire manager ownership without a later
|
||||
call into the dead QObject. Failed release still transfers to the manager, and a committed lease remains its
|
||||
|
||||
+7
-1
@@ -110,7 +110,7 @@ worker. Choose tests by the changed contract rather than by filename alone.
|
||||
| [test_frozenlib.py](test_frozenlib.py) | Nested state guards, cleanup isolation, native peer destruction during connection/theme/translation/cleanup notifications, bounded caches/throttling, dual-stack probe selection, mocked proxy/DNS/routes/startup/session boundaries and failure handling. |
|
||||
| [test_native_tun_semantics.py](test_native_tun_semantics.py) | Xray/Hysteria2 runtime-copy TUN preservation/replacement, managed-TUN failures, download-test stripping, prevention of a second tun2socks owner. |
|
||||
| [test_sing_tun.py](test_sing_tun.py) | tun2socks engine default, saved engine choices and ownership-aware reconnect notices, sing-tun Go stack default, development-stack and congestion-control compatibility, independent backend settings and host defaults, initial and live dialog-button translation, selected-only snapshots, captured TUN log sources in both startup paths, staged settings and malformed storage, SOCKS authentication/UDP, harmless real spawn/status/stop, native readiness, cancellation, synchronous compatibility, mocked DNS/routing ownership including development IPv6 rule ordering and refused cleanup. |
|
||||
| [test_sing_tun_linux_host.py](test_sing_tun_linux_host.py) | Frozenlib sing-tun routing helpers: mocked normal-user and root execution, Bash syntax and isolated script rollback through a fake ip command, user-owned persistent TUN preparation, authorization cancellation/timeouts, retained helper/script ownership, dual-stack route exclusions and policy ordering, iproute2 JSON flags/prefix lengths, interface replacement refusal and exact cleanup retry. No real PolicyKit authorization, TUN, routes or DNS are changed. |
|
||||
| [test_sing_tun_linux_host.py](test_sing_tun_linux_host.py) | Frozenlib sing-tun routing helpers: one authorization for setup/DNS/disconnect, authorization without a deadline and cancellation, retained helper/script ownership, real Bash lifetime and partial rollback through fake ip/resolvectl commands, parent-pipe EOF restoration, user-owned persistent TUN preparation, dual-stack route exclusions and policy ordering, iproute2 JSON flags/prefix lengths/suppression fields, interface replacement refusal and exact cleanup retry. No real PolicyKit authorization, TUN, routes or DNS are changed. |
|
||||
| [test_subscription_sync.py](test_subscription_sync.py) | Group-local preparation/commit, stable duplicate identity, atomic failure, preservation of newer local metadata, rejection of changed source state. |
|
||||
| [test_subscription_manager.py](test_subscription_manager.py) | Stable request generations, provider metadata, batch/partial failures, timer policy, targeted updates, real Stop Updates input, worker responsiveness, cancellation and synchronous shutdown ownership. |
|
||||
| [test_subscription_scalability.py](test_subscription_scalability.py) | Deterministic 1/3/8-group preparation and commit with 1,500 profiles per group and bounded workers; uses the offline benchmark helper. |
|
||||
@@ -122,6 +122,12 @@ worker. Choose tests by the changed contract rather than by filename alone.
|
||||
| [test_log_manager_generation.py](test_log_manager_generation.py) | Reference-model state transitions, concurrency, live/retired ownership, bounded FIFO cleanup, structural complexity, incremental/multiline LogPage rendering; also contains an opt-in generation campaign. |
|
||||
| [test_log_manager_benchmark.py](test_log_manager_benchmark.py) | Data-only report validation, workload compatibility, timing ratios, and real standalone CLI JSON round trips; no performance gates or historical imports. |
|
||||
|
||||
Linux sing-tun asynchronous disconnect is covered in `test_sing_tun.py`: delayed authorization with continued Qt
|
||||
delivery, retained leases and blocked replacement, cancellation without a second prompt, deferred reconnect,
|
||||
observer destruction and shutdown preferences. `test_runtime_lifecycle.py` checks stop-operation timer destruction;
|
||||
`test_architecture_refactors.py` checks that real application exit keeps the event loop and main window available
|
||||
until connection cleanup finishes. These tests mock host changes and do not exercise a real PolicyKit agent.
|
||||
|
||||
### Qt behavior, layout, and lifetime
|
||||
|
||||
| Module | Coverage |
|
||||
|
||||
Reference in New Issue
Block a user