Skip to content

Commit 8d32135

Browse files
author
Anna Gringauze
authored
Fix duplicated scripts and prep to publish dwds (#1414)
* Fix duplicated scripts and prep to publish dwds Make inspector initializer wait on the same future as getScripts call in ChromeProxyService to make sure we populate caches only once. Prep to publish to support file picker work in devtools. Closes: #1413 * Populate script caches only once using async memoizer * Memoize the list of scripts as well * Addressed CR comments
1 parent 6306a2a commit 8d32135

File tree

9 files changed

+8648
-8985
lines changed

9 files changed

+8648
-8985
lines changed

dwds/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## 11.3.1-dev
1+
## 11.4.0
22

3+
- Fix duplicated scripts returned by `VmService.getScripts` API.
34
- Encode extension url asynchronously.
45
- Use default constant port for debug service.
56
- If we fail binding to the port, fall back to previous strategy

dwds/lib/src/debugging/inspector.dart

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
// @dart = 2.9
66

7+
import 'package:async/async.dart';
78
import 'package:logging/logging.dart';
89
import 'package:vm_service/vm_service.dart';
910
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
@@ -29,9 +30,9 @@ import 'libraries.dart';
2930
/// Provides information about currently loaded scripts and objects and support
3031
/// for eval.
3132
class AppInspector extends Domain {
32-
Future<List<ScriptRef>> _cachedScriptRefs;
33+
final _scriptCacheMemoizer = AsyncMemoizer<List<ScriptRef>>();
3334

34-
Future<List<ScriptRef>> get scriptRefs => _cachedScriptRefs ??= _getScripts();
35+
Future<List<ScriptRef>> get scriptRefs => _populateScriptCaches();
3536

3637
final _logger = Logger('AppInspector');
3738

@@ -87,7 +88,7 @@ class AppInspector extends Domain {
8788
isolate.libraries.addAll(libraries);
8889
await DartUri.recordAbsoluteUris(libraries.map((lib) => lib.uri));
8990

90-
var scripts = await _getScripts();
91+
var scripts = await scriptRefs;
9192
await DartUri.recordAbsoluteUris(scripts.map((script) => script.uri));
9293

9394
isolate.extensionRPCs.addAll(await _getExtensionRpcs());
@@ -483,38 +484,38 @@ function($argsString) {
483484
return ScriptList(scripts: await scriptRefs);
484485
}
485486

486-
Future<List<ScriptRef>> _getScripts() async {
487-
await _populateScriptCaches();
488-
return _scriptRefsById.values.toList();
489-
}
490-
491487
/// Request and cache <ScriptRef>s for all the scripts in the application.
492488
///
493489
/// This populates [_scriptRefsById], [_scriptIdToLibraryId] and
494490
/// [_serverPathToScriptRef]. It is a one-time operation, because if we do a
495491
/// reload the inspector will get re-created.
496-
Future<void> _populateScriptCaches() async {
497-
var libraryUris = [for (var library in isolate.libraries) library.uri];
498-
var scripts = await globalLoadStrategy
499-
.metadataProviderFor(appConnection.request.entrypointPath)
500-
.scripts;
501-
// For all the non-dart: libraries, find their parts and create scriptRefs
502-
// for them.
503-
var userLibraries = libraryUris.where((uri) => !uri.startsWith('dart:'));
504-
for (var uri in userLibraries) {
505-
var parts = scripts[uri];
506-
var scriptRefs = [
507-
ScriptRef(uri: uri, id: createId()),
508-
for (var part in parts) ScriptRef(uri: part, id: createId())
509-
];
510-
var libraryRef = await libraryHelper.libraryRefFor(uri);
511-
for (var scriptRef in scriptRefs) {
512-
_scriptRefsById[scriptRef.id] = scriptRef;
513-
_scriptIdToLibraryId[scriptRef.id] = libraryRef.id;
514-
_serverPathToScriptRef[DartUri(scriptRef.uri, _root).serverPath] =
515-
scriptRef;
492+
///
493+
/// Returns the list of scripts refs cached.
494+
Future<List<ScriptRef>> _populateScriptCaches() async {
495+
return _scriptCacheMemoizer.runOnce(() async {
496+
var libraryUris = [for (var library in isolate.libraries) library.uri];
497+
var scripts = await globalLoadStrategy
498+
.metadataProviderFor(appConnection.request.entrypointPath)
499+
.scripts;
500+
// For all the non-dart: libraries, find their parts and create scriptRefs
501+
// for them.
502+
var userLibraries = libraryUris.where((uri) => !uri.startsWith('dart:'));
503+
for (var uri in userLibraries) {
504+
var parts = scripts[uri];
505+
var scriptRefs = [
506+
ScriptRef(uri: uri, id: createId()),
507+
for (var part in parts) ScriptRef(uri: part, id: createId())
508+
];
509+
var libraryRef = await libraryHelper.libraryRefFor(uri);
510+
for (var scriptRef in scriptRefs) {
511+
_scriptRefsById[scriptRef.id] = scriptRef;
512+
_scriptIdToLibraryId[scriptRef.id] = libraryRef.id;
513+
_serverPathToScriptRef[DartUri(scriptRef.uri, _root).serverPath] =
514+
scriptRef;
515+
}
516516
}
517-
}
517+
return _scriptRefsById.values.toList();
518+
});
518519
}
519520

520521
/// Look up the script by id in an isolate.

0 commit comments

Comments
 (0)