refactor: pin the look-alike code paths that must not be merged
Several pairs of near-identical code paths differ in one load-bearing line. Each site now carries a comment naming the invariant that forces it apart, backed by a characterization test so a future deduplication fails loudly instead of silently changing behaviour. Pinned: focusable wrapper vs. chip D-pad activation policy, profile connection cleanup's raw-id vs. ServerId-typed server projections, live TV tab loaders, video player display matching and playback service wiring, track selection container ordering, tracker HTTP client status ladder, and the MediaServerHttpClient shutdown/cancellation contract versus ManagedHttpClient's closing guard. New tests: test/focus/dpad_activation_policy_test.dart test/services/track_selection_container_ordinal_test.dart test/services/trackers/tracker_status_ladder_test.dart test/utils/media_server_http_client_shutdown_test.dart
This commit is contained in:
@@ -14,6 +14,9 @@ Future<http.Response> sendAbortableHttpRequest(
|
||||
Future<void>? abortTrigger,
|
||||
String? operation,
|
||||
}) {
|
||||
// Deliberately not `AbortController`: that type lives with the media-server
|
||||
// client and throws `MediaServerHttpException`, which the tracker/Seerr
|
||||
// callers of this helper must stay independent of.
|
||||
final abort = Completer<void>();
|
||||
void abortRequest() {
|
||||
if (!abort.isCompleted) abort.complete();
|
||||
|
||||
@@ -240,6 +240,9 @@ class _ManagedStreamedResponseWithUrl extends http.StreamedResponse implements h
|
||||
final Uri url;
|
||||
}
|
||||
|
||||
/// Deliberately not `AbortController`: this layer stays a plain [http.Client]
|
||||
/// with no media-server dependency, and it needs two independent latches
|
||||
/// (aborted vs. drained) plus the response canceller.
|
||||
class _TrackedRequest {
|
||||
_TrackedRequest(this.url);
|
||||
|
||||
|
||||
@@ -78,7 +78,16 @@ class AbortController {
|
||||
/// timeouts, logging, and optional endpoint failover.
|
||||
class MediaServerHttpClient {
|
||||
final http.Client _client;
|
||||
|
||||
/// Requests owned by this client, aborted at the transport on shutdown so an
|
||||
/// in-flight body raises [http.RequestAbortedException] instead of truncating.
|
||||
final Set<AbortController> _activeAborts = <AbortController>{};
|
||||
|
||||
/// Not delegated to [ManagedHttpClient]'s own closing guard: that reports
|
||||
/// shutdown as an [http.ClientException], which maps to
|
||||
/// [MediaServerHttpErrorType.connectionError] and so reads as transient.
|
||||
/// Failover, pagination and download retry all branch on
|
||||
/// [MediaServerHttpException.isCancellation].
|
||||
bool _closing = false;
|
||||
|
||||
MediaServerHttpClient({
|
||||
|
||||
Reference in New Issue
Block a user