Skip to content

Commit

Permalink
Improve code structure. (#103)
Browse files Browse the repository at this point in the history
  • Loading branch information
polina-c committed Jul 26, 2023
1 parent 10cce1a commit c53db68
Show file tree
Hide file tree
Showing 40 changed files with 327 additions and 332 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: CI

# TODO(polina-c): configure auto-update for diagrams
# https://github.com/dart-lang/leak_tracker/issues/104

on:
schedule:
# “At 00:00 (UTC) on Sunday.”
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,11 @@ To temporary enable logs, add this line to `main`:
```
Logger.root.onRecord.listen((LogRecord record) => print(record.message));
```

## How to regenerate diagrams

To regenerate diagrams, run:

```
dart run layerlens
```
10 changes: 1 addition & 9 deletions doc/TROUBLESHOOT.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ For collecting debugging information in tests, temporarily pass an instance of `
}, leakTrackingTestConfig: LeakTrackingTestConfig.debug());
```

Or, you can temporarily set global flag, to make all tests collecting debug information:

```
setUpAll(() {
LeakTrackerGlobalFlags.collectDebugInformationForLeaks = true;
});
```

**Applications**

For collecting debugging information in your running application, the options are:
Expand Down Expand Up @@ -111,7 +103,7 @@ also become unreachable, and thus available for garbage collection.

One of signs that some leaks still exist is fixing a leak by releasing link to child in the parent's `dispose`,
because link to not needed parent should be released itself, together with its disposal. If
your fix for a leak is like this, you are defenitely hiding leaks of non-tracked objects:
your fix for a leak is like this, you are defenitely hiding leaks of non-tracked objects:

```
void dispose() {
Expand Down
7 changes: 4 additions & 3 deletions examples/minimal_flutter/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import 'package:flutter/material.dart';
import 'package:leak_tracker/leak_tracker.dart';

void main() {
enableLeakTracking();
MemoryAllocations.instance
.addListener((ObjectEvent event) => dispatchObjectEvent(event.toMap()));
LeakTracking.start();
MemoryAllocations.instance.addListener(
(ObjectEvent event) => LeakTracking.dispatchObjectEvent(event.toMap()),
);

runApp(const MyApp());
}
Expand Down
3 changes: 3 additions & 0 deletions pkgs/leak_tracker/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# 9.0.0

* Remove global flag [collectDebugInformationForLeaks].
* Rename `checkNonGCed` to `checkNotGCed`.
* Group global items related to leak tracking, in abstract class LeakTracking.
* Rename `gcCountBuffer` to `numberOfGcCycles` and `disposalTimeBuffer` to `disposalTime`.

# 8.0.3
Expand Down
2 changes: 1 addition & 1 deletion pkgs/leak_tracker/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ linter:
# - avoid_bool_literals_in_conditional_expressions # not yet tested
# - avoid_catches_without_on_clauses # we do this commonly
# - avoid_catching_errors # we do this commonly
- avoid_classes_with_only_static_members
# - avoid_classes_with_only_static_members
# - avoid_double_and_int_checks # only useful when targeting JS runtime
- avoid_empty_else
- avoid_field_initializers_in_const_classes
Expand Down
4 changes: 2 additions & 2 deletions pkgs/leak_tracker/example/main.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:leak_tracker/leak_tracker.dart';

void main(List<String> arguments) {
enableLeakTracking();
LeakTracking.start();
// ignore: avoid_print
print('Hello, world!');
disableLeakTracking();
LeakTracking.stop();
}
1 change: 0 additions & 1 deletion pkgs/leak_tracker/lib/DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@ Dependencies that create loop are markes with `!`.
flowchart TD;
devtools_integration.dart-->src;
leak_tracker.dart-->src;
testing.dart-->src;
```

4 changes: 2 additions & 2 deletions pkgs/leak_tracker/lib/leak_tracker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// 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.

export 'src/leak_tracking/leak_tracker.dart';
export 'src/leak_tracking/leak_tracker_model.dart';
export 'src/leak_tracking/leak_tracking.dart';
export 'src/leak_tracking/model.dart';
export 'src/leak_tracking/orchestration.dart';
export 'src/shared/shared_model.dart';
export 'src/usage_tracking/model.dart';
Expand Down
1 change: 0 additions & 1 deletion pkgs/leak_tracker/lib/src/DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ flowchart TD;
devtools_integration-->shared;
leak_tracking-->devtools_integration;
leak_tracking-->shared;
testing-->shared;
usage_tracking-->shared;
```

Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ bool registerLeakTrackingServiceExtension() => _registerServiceExtension(
/// Registers service extension for DevTools integration.
///
/// If the extension is already registered, returns false.
bool setupDevToolsIntegration(
ObjectRef<LeakProvider?> leakProvider,
bool initializeDevToolsIntegration(
ObjectRef<WeakReference<LeakProvider>?> leakProvider,
) {
Future<ServiceExtensionResponse> handler(
String method,
Expand All @@ -37,7 +37,7 @@ bool setupDevToolsIntegration(
try {
assert(method == memoryLeakTrackingExtensionName);

final theLeakProvider = leakProvider.value;
final theLeakProvider = leakProvider.value?.target;

if (theLeakProvider == null) {
return ResponseFromApp(LeakTrackingTurnedOffError())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'dart:developer';

import 'package:vm_service/vm_service.dart';

import '../leak_tracking/_formatting.dart';
import '../shared/_formatting.dart';
import '_protocol.dart';
import 'primitives.dart';

Expand Down
23 changes: 13 additions & 10 deletions pkgs/leak_tracker/lib/src/leak_tracking/DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ Dependencies that create loop are markes with `!`.
```mermaid
flowchart TD;
_dispatcher.dart-->_object_tracker.dart;
_leak_checker.dart-->leak_tracker_model.dart;
_leak_reporter.dart-->model.dart;
_leak_tracker.dart-->_leak_reporter.dart;
_leak_tracker.dart-->_object_tracker.dart;
_leak_tracker.dart-->model.dart;
_object_record.dart-->_gc_counter.dart;
_object_tracker.dart-->_finalizer.dart;
_object_tracker.dart-->_gc_counter.dart;
_object_tracker.dart-->_object_record.dart;
_object_tracker.dart-->leak_tracker_model.dart;
_object_tracker.dart-->retaining_path;
leak_tracker.dart-->_dispatcher.dart;
leak_tracker.dart-->_leak_checker.dart;
leak_tracker.dart-->_object_tracker.dart;
leak_tracker.dart-->leak_tracker_model.dart;
orchestration.dart-->_gc_counter.dart;
orchestration.dart-->leak_tracker.dart;
orchestration.dart-->leak_tracker_model.dart;
_object_tracker.dart-->_retaining_path;
_object_tracker.dart-->model.dart;
leak_tracking.dart-->_dispatcher.dart;
leak_tracking.dart-->_leak_tracker.dart;
leak_tracking.dart-->model.dart;
orchestration.dart-->_retaining_path;
orchestration.dart-->leak_tracking.dart;
orchestration.dart-->model.dart;
```

Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import 'dart:async';
import '../devtools_integration/delivery.dart';
import '../shared/_util.dart';
import '../shared/shared_model.dart';
import 'leak_tracker_model.dart';
import 'model.dart';

/// Checks [leakProvider] either by schedule or by request.
///
/// 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,
Expand Down
35 changes: 35 additions & 0 deletions pkgs/leak_tracker/lib/src/leak_tracking/_leak_tracker.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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 '_leak_reporter.dart';
import '_object_tracker.dart';
import 'model.dart';

class LeakTracker {
LeakTracker(LeakTrackingConfiguration config) {
objectTracker = ObjectTracker(
leakDiagnosticConfig: config.leakDiagnosticConfig,
disposalTime: config.disposalTime,
numberOfGcCycles: config.numberOfGcCycles,
maxRequestsForRetainingPath: config.maxRequestsForRetainingPath,
);

leakReporter = LeakReporter(
leakProvider: objectTracker,
checkPeriod: config.checkPeriod,
onLeaks: config.onLeaks,
stdoutSink: config.stdoutLeaks ? StdoutSummarySink() : null,
devToolsSink: config.notifyDevTools ? DevToolsSummarySink() : null,
);
}

late final ObjectTracker objectTracker;

late final LeakReporter leakReporter;

void dispose() {
objectTracker.dispose();
leakReporter.dispose();
}
}
11 changes: 7 additions & 4 deletions pkgs/leak_tracker/lib/src/leak_tracking/_object_tracker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import '../shared/shared_model.dart';
import '_finalizer.dart';
import '_gc_counter.dart';
import '_object_record.dart';
import 'leak_tracker_model.dart';
import 'retaining_path/_connection.dart';
import 'retaining_path/_retaining_path.dart';
import '_retaining_path/_connection.dart';
import '_retaining_path/_retaining_path.dart';
import 'model.dart';

/// Keeps collection of object records until
/// disposal and garbage gollection.
Expand All @@ -27,6 +27,7 @@ class ObjectTracker implements LeakProvider {
this.leakDiagnosticConfig = const LeakDiagnosticConfig(),
required this.disposalTime,
required this.numberOfGcCycles,
required this.maxRequestsForRetainingPath,
FinalizerBuilder? finalizerBuilder,
GcCounter? gcCounter,
IdentityHashCoder? coder,
Expand Down Expand Up @@ -54,6 +55,8 @@ class ObjectTracker implements LeakProvider {

final int numberOfGcCycles;

final int? maxRequestsForRetainingPath;

void startTracking(
Object object, {
required Map<String, dynamic>? context,
Expand Down Expand Up @@ -192,7 +195,7 @@ class ObjectTracker implements LeakProvider {

await processIfNeeded(
items: objectsToGetPath,
limit: LeakTrackerGlobalSettings.maxRequestsForRetainingPath,
limit: maxRequestsForRetainingPath,
processor: _addRetainingPath,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ Dependencies that create loop are markes with `!`.

```mermaid
flowchart TD;
_retaining_path.dart-->_service.dart;
_retaining_path.dart-->_connection.dart;
```

Loading

0 comments on commit c53db68

Please sign in to comment.