diff --git a/pkgs/leak_tracker/CHANGELOG.md b/pkgs/leak_tracker/CHANGELOG.md index 6812bcc7..32691e71 100644 --- a/pkgs/leak_tracker/CHANGELOG.md +++ b/pkgs/leak_tracker/CHANGELOG.md @@ -1,3 +1,7 @@ +# 9.0.0 + +* Rename `gcCountBuffer` to `numberOfGcCycles` and `disposalTimeBuffer` to `disposalTime`. + # 8.0.3 * Fix an issue with custom gcCountBuffer values. diff --git a/pkgs/leak_tracker/lib/src/leak_tracking/_gc_counter.dart b/pkgs/leak_tracker/lib/src/leak_tracking/_gc_counter.dart index 9a6a2e4c..ee1146a4 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/_gc_counter.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/_gc_counter.dart @@ -18,8 +18,8 @@ bool shouldObjectBeGced({ required DateTime timeAtDisposal, required int currentGcCount, required DateTime currentTime, - required Duration disposalTimeBuffer, - required int gcCountBuffer, + required Duration disposalTime, + required int numberOfGcCycles, }) => - currentGcCount - gcCountAtDisposal >= gcCountBuffer && - currentTime.difference(timeAtDisposal) >= disposalTimeBuffer; + currentGcCount - gcCountAtDisposal >= numberOfGcCycles && + currentTime.difference(timeAtDisposal) >= disposalTime; diff --git a/pkgs/leak_tracker/lib/src/leak_tracking/_object_record.dart b/pkgs/leak_tracker/lib/src/leak_tracking/_object_record.dart index 390840fd..b5b9a06c 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/_object_record.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/_object_record.dart @@ -116,7 +116,7 @@ class ObjectRecord { bool get isGCed => _gcedGcCount != null; bool get isDisposed => _disposalGcCount != null; - bool isGCedLateLeak(Duration disposalTimeBuffer, int gcCountBuffer) { + bool isGCedLateLeak(Duration disposalTime, int numberOfGcCycles) { if (_disposalGcCount == null || _gcedGcCount == null) return false; assert(_gcedTime != null); return shouldObjectBeGced( @@ -124,16 +124,16 @@ class ObjectRecord { timeAtDisposal: _disposalTime!, currentGcCount: _gcedGcCount!, currentTime: _gcedTime!, - disposalTimeBuffer: disposalTimeBuffer, - gcCountBuffer: gcCountBuffer, + disposalTime: disposalTime, + numberOfGcCycles: numberOfGcCycles, ); } bool isNotGCedLeak( int currentGcCount, DateTime currentTime, - Duration disposalTimeBuffer, - int gcCountBuffer, + Duration disposalTime, + int numberOfGcCycles, ) { if (_gcedGcCount != null) return false; return shouldObjectBeGced( @@ -141,8 +141,8 @@ class ObjectRecord { timeAtDisposal: _disposalTime!, currentGcCount: currentGcCount, currentTime: currentTime, - disposalTimeBuffer: disposalTimeBuffer, - gcCountBuffer: gcCountBuffer, + disposalTime: disposalTime, + numberOfGcCycles: numberOfGcCycles, ); } diff --git a/pkgs/leak_tracker/lib/src/leak_tracking/_object_tracker.dart b/pkgs/leak_tracker/lib/src/leak_tracking/_object_tracker.dart index 350ea6ed..42035cf9 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/_object_tracker.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/_object_tracker.dart @@ -25,8 +25,8 @@ class ObjectTracker implements LeakProvider { /// The optional parameters are injected for testing purposes. ObjectTracker({ this.leakDiagnosticConfig = const LeakDiagnosticConfig(), - required this.disposalTimeBuffer, - required this.gcCountBuffer, + required this.disposalTime, + required this.numberOfGcCycles, FinalizerBuilder? finalizerBuilder, GcCounter? gcCounter, IdentityHashCoder? coder, @@ -40,7 +40,7 @@ class ObjectTracker implements LeakProvider { late IdentityHashCoder _coder; /// Time to allow the disposal invoker to release the reference to the object. - final Duration disposalTimeBuffer; + final Duration disposalTime; late FinalizerWrapper _finalizer; @@ -52,7 +52,7 @@ class ObjectTracker implements LeakProvider { final LeakDiagnosticConfig leakDiagnosticConfig; - final int gcCountBuffer; + final int numberOfGcCycles; void startTracking( Object object, { @@ -93,7 +93,7 @@ class ObjectTracker implements LeakProvider { final record = _notGCed(code); record.setGCed(_gcCounter.gcCount, clock.now()); - if (record.isGCedLateLeak(disposalTimeBuffer, gcCountBuffer)) { + if (record.isGCedLateLeak(disposalTime, numberOfGcCycles)) { _objects.gcedLateLeaks.add(record); } else if (record.isNotDisposedLeak) { _objects.gcedNotDisposedLeaks.add(record); @@ -181,8 +181,8 @@ class ObjectTracker implements LeakProvider { if (_notGCed(code).isNotGCedLeak( _gcCounter.gcCount, now, - disposalTimeBuffer, - gcCountBuffer, + disposalTime, + numberOfGcCycles, )) { _objects.notGCedDisposedOk.remove(code); _objects.notGCedDisposedLate.add(code); 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 62327738..59b9521a 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker.dart @@ -46,8 +46,8 @@ void enableLeakTracking({ final newTracker = ObjectTracker( leakDiagnosticConfig: theConfig.leakDiagnosticConfig, - disposalTimeBuffer: theConfig.disposalTimeBuffer, - gcCountBuffer: theConfig.gcCountBuffer, + disposalTime: theConfig.disposalTime, + numberOfGcCycles: theConfig.numberOfGcCycles, ); _objectTracker.value = newTracker; diff --git a/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker_model.dart b/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker_model.dart index 2b075b92..d8b678e9 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker_model.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/leak_tracker_model.dart @@ -85,7 +85,7 @@ class LeakDiagnosticConfig { /// /// Theoretically, 2 should be enough, however it gives false positives /// if there is no activity in the application for ~5 minutes. -const defaultGcCountBuffer = 3; +const defaultNumberOfGcCycles = 3; class LeakTrackingConfiguration { const LeakTrackingConfiguration({ @@ -93,9 +93,9 @@ class LeakTrackingConfiguration { this.notifyDevTools = true, this.onLeaks, this.checkPeriod = const Duration(seconds: 1), - this.disposalTimeBuffer = const Duration(milliseconds: 100), + this.disposalTime = const Duration(milliseconds: 100), this.leakDiagnosticConfig = const LeakDiagnosticConfig(), - this.gcCountBuffer = defaultGcCountBuffer, + this.numberOfGcCycles = defaultNumberOfGcCycles, }); /// The leak tracker: @@ -105,18 +105,18 @@ class LeakTrackingConfiguration { /// at the moment of leak checking. LeakTrackingConfiguration.passive({ LeakDiagnosticConfig leakDiagnosticConfig = const LeakDiagnosticConfig(), - int gcCountBuffer = defaultGcCountBuffer, + int numberOfGcCycles = defaultNumberOfGcCycles, }) : this( stdoutLeaks: false, notifyDevTools: false, checkPeriod: null, - disposalTimeBuffer: const Duration(), + disposalTime: const Duration(), leakDiagnosticConfig: leakDiagnosticConfig, - gcCountBuffer: gcCountBuffer, + numberOfGcCycles: numberOfGcCycles, ); /// Number of full GC cycles, enough for a non reachable object to be GCed. - final int gcCountBuffer; + final int numberOfGcCycles; final LeakDiagnosticConfig leakDiagnosticConfig; @@ -135,7 +135,7 @@ class LeakTrackingConfiguration { final LeakSummaryCallback? onLeaks; /// Time to allow the disposal invoker to release the reference to the object. - final Duration disposalTimeBuffer; + final Duration disposalTime; } /// Configuration for leak tracking in unit tests. diff --git a/pkgs/leak_tracker/lib/src/leak_tracking/orchestration.dart b/pkgs/leak_tracker/lib/src/leak_tracking/orchestration.dart index 0c1ff733..8a87334b 100644 --- a/pkgs/leak_tracker/lib/src/leak_tracking/orchestration.dart +++ b/pkgs/leak_tracker/lib/src/leak_tracking/orchestration.dart @@ -45,13 +45,13 @@ class MemoryLeaksDetectedError extends StateError { /// to wait infinitely for the forced garbage collection, that is needed /// to analyse results. /// -/// [gcCountBuffer] is number of full GC cycles, that should be enough for +/// [numberOfGcCycles] is number of full GC cycles, that should be enough for /// a non reachable object to be GCed. /// If after this number of GC cycles a disposed object is still not garbage collected, /// it is considered a notGCed leak. /// Theoretically, the value 1 should be enough, but in practice it creates false /// positives for stale applications. -/// So, recommended value for applications is 3, and for tests is 1. +/// So, recommended value for applications is 3, and for tests is 2. /// /// If you test Flutter widgets, connect their instrumentation to the leak /// tracker: @@ -87,12 +87,12 @@ Future withLeakTracking( Duration? timeoutForFinalGarbageCollection, LeakDiagnosticConfig leakDiagnosticConfig = const LeakDiagnosticConfig(), AsyncCodeRunner? asyncCodeRunner, - int gcCountBuffer = defaultGcCountBuffer, + int numberOfGcCycles = defaultNumberOfGcCycles, }) async { - if (gcCountBuffer <= 0) { + if (numberOfGcCycles <= 0) { throw ArgumentError.value( - gcCountBuffer, - 'gcCountBuffer', + numberOfGcCycles, + 'numberOfGcCycles', 'Must be positive.', ); } @@ -103,7 +103,7 @@ Future withLeakTracking( resetIfAlreadyEnabled: true, config: LeakTrackingConfiguration.passive( leakDiagnosticConfig: leakDiagnosticConfig, - gcCountBuffer: gcCountBuffer, + numberOfGcCycles: numberOfGcCycles, ), ); @@ -123,7 +123,7 @@ Future withLeakTracking( } await forceGC( - fullGcCycles: gcCountBuffer, + fullGcCycles: numberOfGcCycles, timeout: timeoutForFinalGarbageCollection, ); leaks = await collectLeaks(); diff --git a/pkgs/leak_tracker/test/debug/leak_tracking/end_to_end_test.dart b/pkgs/leak_tracker/test/debug/leak_tracking/end_to_end_test.dart index 8991a332..57687116 100644 --- a/pkgs/leak_tracker/test/debug/leak_tracking/end_to_end_test.dart +++ b/pkgs/leak_tracker/test/debug/leak_tracking/end_to_end_test.dart @@ -16,8 +16,9 @@ void main() { tearDown(() => disableLeakTracking()); - for (var gcCountBuffer in [1, defaultGcCountBuffer]) { - test('Leak tracker respects maxRequestsForRetainingPath, $gcCountBuffer.', + for (var numberOfGcCycles in [1, defaultNumberOfGcCycles]) { + test( + 'Leak tracker respects maxRequestsForRetainingPath, $numberOfGcCycles.', () async { LeakTrackerGlobalSettings.maxRequestsForRetainingPath = 2; final leaks = await withLeakTracking( @@ -30,7 +31,7 @@ void main() { leakDiagnosticConfig: const LeakDiagnosticConfig( collectRetainingPathForNonGCed: true, ), - gcCountBuffer: gcCountBuffer, + numberOfGcCycles: numberOfGcCycles, ); const pathHeader = ' path: >'; @@ -52,7 +53,7 @@ void main() { ); }); - test('Retaining path for not GCed object is reported, $gcCountBuffer.', + test('Retaining path for not GCed object is reported, $numberOfGcCycles.', () async { final leaks = await withLeakTracking( () async { @@ -62,7 +63,7 @@ void main() { leakDiagnosticConfig: const LeakDiagnosticConfig( collectRetainingPathForNonGCed: true, ), - gcCountBuffer: gcCountBuffer, + numberOfGcCycles: numberOfGcCycles, ); const expectedRetainingPathTails = [ diff --git a/pkgs/leak_tracker/test/release/leak_tracking/_gc_counter_test.dart b/pkgs/leak_tracker/test/release/leak_tracking/_gc_counter_test.dart index 2538e629..ef38e7b7 100644 --- a/pkgs/leak_tracker/test/release/leak_tracking/_gc_counter_test.dart +++ b/pkgs/leak_tracker/test/release/leak_tracking/_gc_counter_test.dart @@ -10,7 +10,7 @@ void main() { test('shouldObjectBeGced', () { final now = DateTime(2022); const gcNow = 1000; - const disposalTimeBuffer = Duration(milliseconds: 100); + const timeToDispose = Duration(milliseconds: 100); bool shouldBeGced(int disposalGcCount, DateTime disposalTime) => shouldObjectBeGced( @@ -18,8 +18,8 @@ void main() { timeAtDisposal: disposalTime, currentGcCount: gcNow, currentTime: now, - disposalTimeBuffer: disposalTimeBuffer, - gcCountBuffer: defaultGcCountBuffer, + disposalTime: timeToDispose, + numberOfGcCycles: defaultNumberOfGcCycles, ); final forJustGcEd = shouldBeGced(gcNow, now); @@ -33,8 +33,8 @@ void main() { expect(forNotEnoughGc, isFalse); final forEnoughTimeAndGc = shouldBeGced( - gcNow - defaultGcCountBuffer, - now.subtract(disposalTimeBuffer), + gcNow - defaultNumberOfGcCycles, + now.subtract(timeToDispose), ); expect(forEnoughTimeAndGc, isTrue); }); diff --git a/pkgs/leak_tracker/test/release/leak_tracking/_object_tracker_test.dart b/pkgs/leak_tracker/test/release/leak_tracking/_object_tracker_test.dart index 5b7fcac5..dc8541e8 100644 --- a/pkgs/leak_tracker/test/release/leak_tracking/_object_tracker_test.dart +++ b/pkgs/leak_tracker/test/release/leak_tracking/_object_tracker_test.dart @@ -11,7 +11,7 @@ import 'package:leak_tracker/src/shared/_primitives.dart'; import 'package:test/test.dart'; const String _trackedClass = 'trackedClass'; -const _disposalTimeBuffer = Duration(milliseconds: 100); +const _disposalTime = Duration(milliseconds: 100); void main() { group('processIfNeeded', () { @@ -78,9 +78,9 @@ void main() { setUp(() { tracker = ObjectTracker( - disposalTimeBuffer: _disposalTimeBuffer, + disposalTime: _disposalTime, coder: mockCoder, - gcCountBuffer: defaultGcCountBuffer, + numberOfGcCycles: defaultNumberOfGcCycles, ); }); @@ -145,8 +145,8 @@ void main() { tracker = ObjectTracker( finalizerBuilder: finalizerBuilder.build, gcCounter: gcCounter, - disposalTimeBuffer: _disposalTimeBuffer, - gcCountBuffer: defaultGcCountBuffer, + disposalTime: _disposalTime, + numberOfGcCycles: defaultNumberOfGcCycles, ); }); @@ -170,8 +170,8 @@ void main() { }); // Time travel. - time = time.add(_disposalTimeBuffer * 1000); - gcCounter.gcCount = gcCounter.gcCount + defaultGcCountBuffer * 1000; + time = time.add(_disposalTime * 1000); + gcCounter.gcCount = gcCounter.gcCount + defaultNumberOfGcCycles * 1000; // Verify no leaks. withClock(Clock.fixed(time), () { @@ -211,8 +211,8 @@ void main() { }); // Time travel. - time = time.add(_disposalTimeBuffer); - gcCounter.gcCount = gcCounter.gcCount + defaultGcCountBuffer; + time = time.add(_disposalTime); + gcCounter.gcCount = gcCounter.gcCount + defaultNumberOfGcCycles; // Verify leak is registered. await withClock(Clock.fixed(time), () async { @@ -236,8 +236,8 @@ void main() { }); // Time travel. - time = time.add(_disposalTimeBuffer); - gcCounter.gcCount = gcCounter.gcCount + defaultGcCountBuffer; + time = time.add(_disposalTime); + gcCounter.gcCount = gcCounter.gcCount + defaultNumberOfGcCycles; // GC and verify leak is registered. await withClock(Clock.fixed(time), () async { @@ -262,8 +262,8 @@ void main() { }); // Time travel. - time = time.add(_disposalTimeBuffer); - gcCounter.gcCount = gcCounter.gcCount + defaultGcCountBuffer; + time = time.add(_disposalTime); + gcCounter.gcCount = gcCounter.gcCount + defaultNumberOfGcCycles; await withClock(Clock.fixed(time), () async { // Verify notGCed leak is registered. @@ -292,8 +292,8 @@ void main() { }); // Time travel. - time = time.add(_disposalTimeBuffer); - gcCounter.gcCount = gcCounter.gcCount + defaultGcCountBuffer; + time = time.add(_disposalTime); + gcCounter.gcCount = gcCounter.gcCount + defaultNumberOfGcCycles; // Verify context for the collected nonGCed. await withClock(Clock.fixed(time), () async { @@ -321,8 +321,8 @@ void main() { classesToCollectStackTraceOnStart: {'String'}, classesToCollectStackTraceOnDisposal: {'String'}, ), - disposalTimeBuffer: _disposalTimeBuffer, - gcCountBuffer: defaultGcCountBuffer, + disposalTime: _disposalTime, + numberOfGcCycles: defaultNumberOfGcCycles, ); }); @@ -342,8 +342,8 @@ void main() { }); // Time travel. - time = time.add(_disposalTimeBuffer); - gcCounter.gcCount = gcCounter.gcCount + defaultGcCountBuffer; + time = time.add(_disposalTime); + gcCounter.gcCount = gcCounter.gcCount + defaultNumberOfGcCycles; // GC and verify leak contains callstacks. await withClock(Clock.fixed(time), () async { diff --git a/pkgs/leak_tracker/test/release/leak_tracking/end_to_end_test.dart b/pkgs/leak_tracker/test/release/leak_tracking/end_to_end_test.dart index 8176f7c5..f13e1e54 100644 --- a/pkgs/leak_tracker/test/release/leak_tracking/end_to_end_test.dart +++ b/pkgs/leak_tracker/test/release/leak_tracking/end_to_end_test.dart @@ -16,14 +16,14 @@ void main() { disableLeakTracking(); }); - for (var gcCountBuffer in [1, defaultGcCountBuffer]) { - test('Not disposed object reported, $gcCountBuffer.', () async { + for (var numberOfGcCycles in [1, defaultNumberOfGcCycles]) { + test('Not disposed object reported, $numberOfGcCycles.', () async { final leaks = await withLeakTracking( () async { LeakTrackedClass(); }, shouldThrowOnLeaks: false, - gcCountBuffer: gcCountBuffer, + numberOfGcCycles: numberOfGcCycles, ); expect(() => expect(leaks, isLeakFree), throwsException); @@ -34,7 +34,7 @@ void main() { expect(theLeak.trackedClass, contains('$LeakTrackedClass')); }); - test('Not GCed object reported, $gcCountBuffer.', () async { + test('Not GCed object reported, $numberOfGcCycles.', () async { late LeakTrackedClass notGCedObject; final leaks = await withLeakTracking( () async { @@ -43,7 +43,7 @@ void main() { notGCedObject.dispose(); }, shouldThrowOnLeaks: false, - gcCountBuffer: gcCountBuffer, + numberOfGcCycles: numberOfGcCycles, ); expect(() => expect(leaks, isLeakFree), throwsException); @@ -54,7 +54,8 @@ void main() { expect(theLeak.trackedClass, contains('$LeakTrackedClass')); }); - test('Retaining path cannot be collected in release mode, $gcCountBuffer.', + test( + 'Retaining path cannot be collected in release mode, $numberOfGcCycles.', () async { late LeakTrackedClass notGCedObject; Future test() async { @@ -68,7 +69,7 @@ void main() { leakDiagnosticConfig: const LeakDiagnosticConfig( collectRetainingPathForNonGCed: true, ), - gcCountBuffer: gcCountBuffer, + numberOfGcCycles: numberOfGcCycles, ); } @@ -82,17 +83,18 @@ void main() { ); }); - test('$isLeakFree succeeds, $gcCountBuffer.', () async { + test('$isLeakFree succeeds, $numberOfGcCycles.', () async { final leaks = await withLeakTracking( () async {}, shouldThrowOnLeaks: false, - gcCountBuffer: gcCountBuffer, + numberOfGcCycles: numberOfGcCycles, ); expect(leaks, isLeakFree); }); - test('Stack trace does not start with leak tracker calls, $gcCountBuffer.', + test( + 'Stack trace does not start with leak tracker calls, $numberOfGcCycles.', () async { final leaks = await withLeakTracking( () async { @@ -103,7 +105,7 @@ void main() { collectStackTraceOnStart: true, collectStackTraceOnDisposal: true, ), - gcCountBuffer: gcCountBuffer, + numberOfGcCycles: numberOfGcCycles, ); try { diff --git a/pkgs/leak_tracker/test/test_infra/mocks/mock_object_tracker.dart b/pkgs/leak_tracker/test/test_infra/mocks/mock_object_tracker.dart index a077f444..797a8ac9 100644 --- a/pkgs/leak_tracker/test/test_infra/mocks/mock_object_tracker.dart +++ b/pkgs/leak_tracker/test/test_infra/mocks/mock_object_tracker.dart @@ -22,9 +22,9 @@ class Event { class MockObjectTracker extends ObjectTracker { MockObjectTracker() : super( - disposalTimeBuffer: const Duration(milliseconds: 100), + disposalTime: const Duration(milliseconds: 100), leakDiagnosticConfig: const LeakDiagnosticConfig(), - gcCountBuffer: defaultGcCountBuffer, + numberOfGcCycles: defaultNumberOfGcCycles, ); final events = []; 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 index f34f4e94..1924667a 100644 --- 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 @@ -22,9 +22,9 @@ class Event { class MockObjectTracker extends ObjectTracker { MockObjectTracker() : super( - disposalTimeBuffer: const Duration(milliseconds: 100), + disposalTime: const Duration(milliseconds: 100), leakDiagnosticConfig: const LeakDiagnosticConfig(), - gcCountBuffer: 3, + numberOfGcCycles: 3, ); final events = [];