From 8939456ccc296a884530c104d960df98fd3b8255 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 4 Aug 2023 07:02:01 -0700 Subject: [PATCH] Refactor dispatcher. (#115) --- .../lib/src/leak_tracking/DEPENDENCIES.md | 2 - .../{ => _primitives}/_dispatcher.dart | 34 ++++++++----- .../lib/src/leak_tracking/leak_tracking.dart | 8 +++- .../test/test_infra/event_tracker.dart | 40 ++++++++++++++++ .../test/test_infra/mock_object_tracker.dart | 48 ------------------- .../test/tests/_dispatcher_test.dart | 19 +++++--- 6 files changed, 80 insertions(+), 71 deletions(-) rename pkgs/leak_tracker/lib/src/leak_tracking/{ => _primitives}/_dispatcher.dart (67%) create mode 100644 pkgs/leak_tracker_flutter_test/test/test_infra/event_tracker.dart delete mode 100644 pkgs/leak_tracker_flutter_test/test/test_infra/mock_object_tracker.dart diff --git a/pkgs/leak_tracker/lib/src/leak_tracking/DEPENDENCIES.md b/pkgs/leak_tracker/lib/src/leak_tracking/DEPENDENCIES.md index fe518e59..83c0ab80 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/DEPENDENCIES.md +++ b/pkgs/leak_tracker/lib/src/leak_tracking/DEPENDENCIES.md @@ -5,7 +5,6 @@ Dependencies that create loop are markes with `!`. ```mermaid flowchart TD; -_dispatcher.dart-->_object_tracker.dart; _leak_filter.dart-->_object_record.dart; _leak_filter.dart-->_primitives; _leak_reporter.dart-->_primitives; @@ -16,7 +15,6 @@ _object_record.dart-->_primitives; _object_tracker.dart-->_leak_filter.dart; _object_tracker.dart-->_object_record.dart; _object_tracker.dart-->_primitives; -leak_tracking.dart-->_dispatcher.dart; leak_tracking.dart-->_leak_tracker.dart; leak_tracking.dart-->_primitives; orchestration.dart-->_primitives; diff --git a/pkgs/leak_tracker/lib/src/leak_tracking/_dispatcher.dart b/pkgs/leak_tracker/lib/src/leak_tracking/_primitives/_dispatcher.dart similarity index 67% rename from pkgs/leak_tracker/lib/src/leak_tracking/_dispatcher.dart rename to pkgs/leak_tracker/lib/src/leak_tracking/_primitives/_dispatcher.dart index df634ba2..fd8d44de 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/_dispatcher.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/_primitives/_dispatcher.dart @@ -2,9 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import '../shared/_primitives.dart'; -import '_object_tracker.dart'; - // Values in [FieldNames] and [EventType] should be identical to ones used in // https://github.com/flutter/flutter/blob/a479718b02a818fb4ac8d4900bf08ca389cd8e7d/packages/flutter/lib/src/foundation/memory_allocations.dart#L23 @@ -19,12 +16,23 @@ class _EventType { static const String disposed = 'disposed'; } -void dispatchObjectEvent( - Map> event, - ObjectTracker? objectTracker, -) { - if (objectTracker == null) return; +typedef StartTrackingCallback = void Function({ + required Object object, + required Map? context, + required String library, + required String className, +}); +typedef DispatchDisposalCallback = void Function({ + required Object object, + required Map? context, +}); + +void dispatchObjectEvent( + Map> event, { + required StartTrackingCallback onStartTracking, + required DispatchDisposalCallback onDispatchDisposal, +}) { assert(event.length == 1); final entry = event.entries.first; @@ -37,14 +45,14 @@ void dispatchObjectEvent( final className = fields[_FieldNames.className]?.toString() ?? ''; if (eventType == _EventType.created) { - objectTracker.startTracking( - object, + onStartTracking( + object: object, context: null, - trackedClass: - fullClassName(library: libraryName, shortClassName: className), + library: libraryName, + className: className, ); } else if (eventType == _EventType.disposed) { - objectTracker.dispatchDisposal(object, context: null); + onDispatchDisposal(object: object, context: null); } else { throw StateError('Unexpected event type for $object: $eventType.'); } diff --git a/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracking.dart b/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracking.dart index 711d0c0b..e90644b4 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracking.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracking.dart @@ -5,8 +5,8 @@ import '../devtools_integration/_registration.dart'; import '../shared/_primitives.dart'; import '../shared/shared_model.dart'; -import '_dispatcher.dart' as dispatcher; import '_leak_tracker.dart'; +import '_primitives/_dispatcher.dart' as dispatcher; import '_primitives/model.dart'; /// Provides leak tracking functionality. @@ -93,7 +93,11 @@ abstract class LeakTracking { /// https://github.com/flutter/flutter/blob/a479718b02a818fb4ac8d4900bf08ca389cd8e7d/packages/flutter/lib/src/foundation/memory_allocations.dart#L51 static void dispatchObjectEvent(Map> event) { assert(() { - dispatcher.dispatchObjectEvent(event, _leakTracker?.objectTracker); + dispatcher.dispatchObjectEvent( + event, + onStartTracking: dispatchObjectCreated, + onDispatchDisposal: dispatchObjectDisposed, + ); return true; }()); } diff --git a/pkgs/leak_tracker_flutter_test/test/test_infra/event_tracker.dart b/pkgs/leak_tracker_flutter_test/test/test_infra/event_tracker.dart new file mode 100644 index 00000000..d42ff01a --- /dev/null +++ b/pkgs/leak_tracker_flutter_test/test/test_infra/event_tracker.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +enum EventType { + started, + disposed, +} + +class Event { + Event(this.type, this.object, this.context, this.library, this.className); + + final EventType type; + final Object object; + final Map? context; + final String? library; + final String? className; +} + +class EventTracker { + EventTracker(); + + final events = []; + + void dispatchObjectCreated({ + required String library, + required String className, + required Object object, + Map? context, + }) { + events.add(Event(EventType.started, object, context, library, className)); + } + + void dispatchObjectDisposed({ + required Object object, + Map? context, + }) { + events.add(Event(EventType.disposed, object, context, null, null)); + } +} diff --git a/pkgs/leak_tracker_flutter_test/test/test_infra/mock_object_tracker.dart b/pkgs/leak_tracker_flutter_test/test/test_infra/mock_object_tracker.dart deleted file mode 100644 index e7c5d338..00000000 --- a/pkgs/leak_tracker_flutter_test/test/test_infra/mock_object_tracker.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:leak_tracker/leak_tracker.dart'; -import 'package:leak_tracker/src/leak_tracking/_object_tracker.dart'; -import 'package:leak_tracker/src/shared/_primitives.dart'; - -enum EventType { - started, - disposed, -} - -class Event { - Event(this.type, this.object, this.context, this.trackedClass); - - final EventType type; - final Object object; - final Map? context; - final String? trackedClass; -} - -class MockObjectTracker extends ObjectTracker { - MockObjectTracker() - : super( - disposalTime: const Duration(milliseconds: 100), - numberOfGcCycles: 3, - maxRequestsForRetainingPath: 10, - phase: ObjectRef(const PhaseSettings()), - ); - - final events = []; - - @override - void startTracking( - Object object, { - required Map? context, - required String trackedClass, - }) => - events.add(Event(EventType.started, object, context, trackedClass)); - - @override - void dispatchDisposal( - Object object, { - required Map? context, - }) => - events.add(Event(EventType.disposed, object, context, null)); -} diff --git a/pkgs/leak_tracker_flutter_test/test/tests/_dispatcher_test.dart b/pkgs/leak_tracker_flutter_test/test/tests/_dispatcher_test.dart index a18d963d..fc3fb624 100644 --- a/pkgs/leak_tracker_flutter_test/test/tests/_dispatcher_test.dart +++ b/pkgs/leak_tracker_flutter_test/test/tests/_dispatcher_test.dart @@ -6,15 +6,21 @@ import 'dart:ui'; import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:leak_tracker/src/leak_tracking/_dispatcher.dart'; +import 'package:leak_tracker/src/leak_tracking/_primitives/_dispatcher.dart'; -import '../test_infra/mock_object_tracker.dart'; +import '../test_infra/event_tracker.dart'; void main() { test('dispatchObjectEvent dispatches Flutter SDK instrumentation.', () { - final tracker = MockObjectTracker(); - MemoryAllocations.instance - .addListener((event) => dispatchObjectEvent(event.toMap(), tracker)); + final tracker = EventTracker(); + + MemoryAllocations.instance.addListener( + (event) => dispatchObjectEvent( + event.toMap(), + onStartTracking: tracker.dispatchObjectCreated, + onDispatchDisposal: tracker.dispatchObjectDisposed, + ), + ); final picture = _createPicture(); @@ -24,7 +30,8 @@ void main() { expect(event.type, EventType.started); expect(event.object, picture); expect(event.context, null); - expect(event.trackedClass, 'dart:ui/Picture'); + expect(event.className, 'Picture'); + expect(event.library, 'dart:ui'); picture.dispose();