From ab158a7afb160722836d6b39b805a21836f50b49 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Tue, 25 Jul 2023 11:50:44 -0700 Subject: [PATCH] - --- ..._leak_checker.dart => _leak_reporter.dart} | 4 +- .../{leak_tracker.dart => _leak_tracker.dart} | 7 +- .../src/leak_tracking/leak_tracker___.dart | 6 +- .../lib/src/leak_tracking/leak_tracking.dart | 69 ++++++++++++++++++- .../leak_tracking/_leak_checker_test.dart | 8 +-- 5 files changed, 78 insertions(+), 16 deletions(-) rename pkgs/leak_tracker/lib/src/leak_tracking/{_leak_checker.dart => _leak_reporter.dart} (98%) rename pkgs/leak_tracker/lib/src/leak_tracking/{leak_tracker.dart => _leak_tracker.dart} (81%) diff --git a/pkgs/leak_tracker/lib/src/leak_tracking/_leak_checker.dart b/pkgs/leak_tracker/lib/src/leak_tracking/_leak_reporter.dart similarity index 98% rename from pkgs/leak_tracker/lib/src/leak_tracking/_leak_checker.dart rename to pkgs/leak_tracker/lib/src/leak_tracking/_leak_reporter.dart index e5363b42..c24e58f1 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/_leak_checker.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/_leak_reporter.dart @@ -13,8 +13,8 @@ import 'model.dart'; /// /// If there are leaks, reports them to the enabled outputs: /// listener, console and DevTools. -class LeakChecker { - LeakChecker({ +class LeakReporter { + LeakReporter({ required this.leakProvider, required this.checkPeriod, required this.onLeaks, diff --git a/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker.dart b/pkgs/leak_tracker/lib/src/leak_tracking/_leak_tracker.dart similarity index 81% rename from pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker.dart rename to pkgs/leak_tracker/lib/src/leak_tracking/_leak_tracker.dart index 06de769d..d7e7b969 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/_leak_tracker.dart @@ -6,12 +6,11 @@ import '../devtools_integration/_registration.dart'; import '../shared/_primitives.dart'; import '../shared/shared_model.dart'; import '_dispatcher.dart' as dispatcher; -import '_leak_checker.dart'; +import '_leak_reporter.dart'; import '_object_tracker.dart'; import 'model.dart'; class LeakTracker { - // static LeakTracker? _leakTracker; - - // LeakProvider? + final ObjectTracker _objectTracker; + final LeakReporter _leakChecker; } diff --git a/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker___.dart b/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker___.dart index 980e3324..5e710a86 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker___.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker___.dart @@ -6,7 +6,7 @@ import '../devtools_integration/_registration.dart'; import '../shared/_primitives.dart'; import '../shared/shared_model.dart'; import '_dispatcher.dart' as dispatcher; -import '_leak_checker.dart'; +import '_leak_reporter.dart'; import '_object_tracker.dart'; import 'model.dart'; @@ -14,7 +14,7 @@ class LeakTracker {} final _objectTracker = ObjectRef(null); -LeakChecker? _leakChecker; +LeakReporter? _leakChecker; ObjectTracker _theObjectTracker() { // TODO(polina-c): return both tracker and checker when tuples get released. @@ -55,7 +55,7 @@ void enableLeakTracking({ _objectTracker.value = newTracker; - _leakChecker = LeakChecker( + _leakChecker = LeakReporter( leakProvider: newTracker, checkPeriod: theConfig.checkPeriod, onLeaks: theConfig.onLeaks, 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 053ca575..7e523eb4 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracking.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracking.dart @@ -8,15 +8,78 @@ import '../devtools_integration/_registration.dart'; import '../shared/_primitives.dart'; import '../shared/shared_model.dart'; import '_dispatcher.dart' as dispatcher; -import '_leak_checker.dart'; +import '_leak_reporter.dart'; import '_object_tracker.dart'; import 'model.dart'; abstract class LeakTracking { static LeakTracker? _leakTracker; - /// Leak provider, used in integration with DevTools. + /// Leak provider, used for integration with DevTools. /// /// It should be updated every time leak tracking is reconfigured. - static final _leakProvider = ObjectRef(null); + static final _leakProvider = ObjectRef?>(null); + + /// Enables leak tracking for the application. + /// + /// The leak tracking will function only for debug/profile/developer mode. + /// See usage guidance at https://github.com/dart-lang/leak_tracker. + /// + /// If [resetIfAlreadyEnabled] is true and leak tracking is already on, + /// the tracking will be reset with new configuration. + /// + /// If [resetIfAlreadyEnabled] is true and leak tracking is already on, + /// [StateError] will be thrown. + void enableLeakTracking({ + LeakTrackingConfiguration? config, + bool resetIfAlreadyEnabled = false, + }) { + assert(() { + final theConfig = config ??= const LeakTrackingConfiguration(); + if (_leakTracker != null) { + if (!resetIfAlreadyEnabled) { + throw StateError('Leak tracking is already enabled.'); + } + disableLeakTracking(); + } + + final objectTracker = ObjectTracker( + leakDiagnosticConfig: theConfig.leakDiagnosticConfig, + disposalTime: theConfig.disposalTime, + numberOfGcCycles: theConfig.numberOfGcCycles, + ); + + final leakChecker = LeakReporter( + leakProvider: objectTracker, + checkPeriod: theConfig.checkPeriod, + onLeaks: theConfig.onLeaks, + stdoutSink: theConfig.stdoutLeaks ? StdoutSummarySink() : null, + devToolsSink: theConfig.notifyDevTools ? DevToolsSummarySink() : null, + ); + + _leakProvider.value = WeakReference(objectTracker); + + if (theConfig.notifyDevTools) { + setupDevToolsIntegration(_leakProvider); + } else { + registerLeakTrackingServiceExtension(); + } + return true; + }()); + } + + /// Disables leak tracking for the application. + /// + /// See usage guidance at https://github.com/dart-lang/leak_tracker. + void disableLeakTracking() { + assert(() { + _leakProvider.value?.dispose(); + _leakChecker?.dispose(); + _leakChecker = null; + _objectTracker.value?.dispose(); + _objectTracker.value = null; + + return true; + }()); + } } diff --git a/pkgs/leak_tracker/test/release/leak_tracking/_leak_checker_test.dart b/pkgs/leak_tracker/test/release/leak_tracking/_leak_checker_test.dart index 7c1074fd..52b1d9dd 100644 --- a/pkgs/leak_tracker/test/release/leak_tracking/_leak_checker_test.dart +++ b/pkgs/leak_tracker/test/release/leak_tracking/_leak_checker_test.dart @@ -3,7 +3,7 @@ // 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/_leak_checker.dart'; +import 'package:leak_tracker/src/leak_tracking/_leak_reporter.dart'; import 'package:test/test.dart'; // Enum-like static classes are ok. @@ -31,13 +31,13 @@ void main() { const period = Duration(milliseconds: 5); late final doublePeriod = Duration(microseconds: period.inMicroseconds); - LeakChecker leakChecker({ + LeakReporter leakChecker({ required bool checkPeriodically, required bool hasListener, required bool hasStdout, required bool hasDevtools, }) => - LeakChecker( + LeakReporter( leakProvider: leakProvider, checkPeriod: checkPeriodically ? period : null, onLeaks: hasListener ? (summary) => listened.store.add(summary) : null, @@ -45,7 +45,7 @@ void main() { devToolsSink: hasDevtools ? devtools : null, ); - LeakChecker defaultLeakChecker() => leakChecker( + LeakReporter defaultLeakChecker() => leakChecker( checkPeriodically: true, hasListener: false, hasStdout: true,