Skip to content

Conversation

@jonahwilliams
Copy link
Contributor

@jonahwilliams jonahwilliams commented Feb 19, 2020

Update to latest dwds APIs, moving back to dwds driven hot restart and enabling future work on expression evaluation.

@grouma
@annagrin

Fixes #52193

@fluttergithubbot fluttergithubbot added c: contributor-productivity Team-specific productivity, code health, technical debt. tool Affects the "flutter" command-line tool. See also t: labels. work in progress; do not review labels Feb 19, 2020
@jonahwilliams jonahwilliams changed the title Devtools stuff [flutter_tools] Update to latest dwds APIs Feb 19, 2020
return null;
}
}
var module = window.\$requireLoader.urlToModuleId.get(url)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the dartLoader doesn't exist anymore - should I be using the requireLoader? Otherwise I'm not sure exactly what this code should look like. I tried a few permutations but they all crash

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't need either. You are correct that the dartLoader was removed and replaced with reqruireLoader. However, package:dwds now embeds the requrieLoader in the entry bootstrap.

See here:
https://github.com/dart-lang/webdev/blob/master/dwds/lib/src/handlers/injected_handler.dart#L74

And here:
https://github.com/dart-lang/webdev/blob/master/dwds/lib/src/loaders/require.dart#L179

Let me know if removing this doesn't fix your problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing SGTM, but I don't see any handling of the dartStackTraceUtility in the new dwds code

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakemac53 said that logic was safe to remove. He can probably provide more context.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another difference is that If I throw an unhandled exception, before the stackTraceMapper would first be called with a url like http://localhost:53973/dart_sdk.js that would be mapped to the module name dart_sdk. Now it's failing with http://localhost:53973/something/dart_stack_trace_mapper.js which might indicate something isn't getting set up correctly. Still investigating

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it needs to be added by build_web_compilers - it has its own version. Flutter also i think has its own version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an equivalent to this line I need to do for the requireLoader?

https://github.com/dart-lang/build/blob/8c8ed2b52357b62971889ab2c8c26db2163c0080/build_web_compilers/lib/src/dev_compiler_bootstrap.dart#L366

I'm currrently using the following code:

  dart_sdk._isolate_helper.startRootIsolate(() => {}, []);
  if (window.\$dartStackTraceUtility && !window.\$dartStackTraceUtility.ready) {
    window.\$dartStackTraceUtility.ready = true;
    let dart = dart_sdk.dart;
    window.\$dartStackTraceUtility.setSourceMapProvider(function(url) {
      url = url.replace(window.\$dartUriBase, '');
      var module = window.\$requireLoader.urlToModuleId.get(url);
      if (!module) return;
      return dart.getSourceMap(url);
    });
  }

But I'm only get url from the stack trace mapper itself, which leads me to believe that I set it up incorrectly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is not but I'm happy to add it to package:dwds somewhere here: https://github.com/dart-lang/webdev/blob/master/dwds/lib/src/loaders/require.dart#L222

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its not so much what API goes into dwds, there is a slight bug now since we use the stack trace mapper from the SDK. This expects there to be a field called window.$dartLoader.rootDirectories:

https://github.com/dart-lang/sdk/blob/master/pkg/dev_compiler/web/stack_trace_mapper.dart#L39

All stack traces actually are crashing in the stack trace mapper now. I can work around by defining this in the bootstrap script myself

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh I see. I'm thinking we just duplicate window.$dratLoader.rootDirectories in the DWDS bootstrap for now and eventually clean up the SDK.

@jonahwilliams
Copy link
Contributor Author

Everything seems to working for the most part, except the hot restarts are requesting more resources than necessary and doing full page reloads. I think I've misconfigured something with the modules/digests, but I'm not sure where

@jonahwilliams
Copy link
Contributor Author

So far I've discovered that the special entrypoint in temp seems to be throwing off the module naming. It works a bit better if I stick packages/packagename in front of the module name. Still not reload correctly as client.js can't seem to match the right extension in the $requireLoader urlToModule

@grouma
Copy link
Member

grouma commented Feb 24, 2020

@annagrin has been running into similar issues while testing. Let's put this on hold for now and I'll dig through the issue with her.

@jonahwilliams
Copy link
Contributor Author

It might help if we could relax the requirement to use either a multiroot scheme or a package scheme. That would at least simplify some of the paths used and server configuration.

bool useBuildRunner = false,
String coverage,
bq.TabledataResourceApi tableData,
bool forceSingleCore = false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this change, we would try to spin up multiple chrome instances and stall. I'm also suspicious that some of the previous flakes in integration tests were caused by having multiple flutter_tester shells active.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go in a comment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting. Do you not use the concurrency parameter of package:test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do, but by default it gets set to the number of cores that the bot has.

Copy link
Contributor

@yjbanov yjbanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if LGT @grouma

bool useBuildRunner = false,
String coverage,
bq.TabledataResourceApi tableData,
bool forceSingleCore = false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting. Do you not use the concurrency parameter of package:test?

@override
Future<String> dartSourceContents(String serverPath) {
Future<String> dartSourceContents(String serverPath) async {
if (serverPath == null || serverPath.trim().isEmpty) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an interesting guard. Not that it's wrong by does package:dwds ever request null paths?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that devtools was requesting null paths before the change to the tracked library names. I will re-verify this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated - we only get a null path when devtools tries to request the web-entrypoint file with the org-dartlang-app scheme. I made this check more specific, but we should probably fix/hide this file otherwise

document.head.appendChild(requireEl);
// Invoked by connected chrome debugger for hot reload/restart support.
window.\$hotReloadHook = function(modules) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love this cleanup!

return dart.getSourceMap(module);
});
}
dart_sdk._isolate_helper.startRootIsolate(() => {}, []);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with this. What is this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I copied this from the build_runner tooling, so its probably just a straggler. Will remove once I verify its not necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary removed

// Require JS configuration.
require.config({
waitSeconds: 0,
window.\$dartLoader = {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the dartLoader stuff required? Shouldn't be anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need this since we're using the stack trace mapper from the SDK, and that code unconditionally refers to these getters

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes. Hmmm. We should reconsider that at one point.

tempDirectory = createResolvedTempDirectorySync('debugger_stepping_test.');
});

test('Web debugger can step over statements', () async {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice.

final String suffix = Platform.isWindows && subshard == 'commands'
? 'permeable'
: '';
final bool forceSingleCore = Platform.isLinux && subshard == 'integration';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why only Linux? (Add a comment explaining)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comment

bool useBuildRunner = false,
String coverage,
bq.TabledataResourceApi tableData,
bool forceSingleCore = false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go in a comment.

} else {
cpus = 2; // Don't default to 1, otherwise we won't catch race conditions.
}
// Integration tests that depend on external processes like chrome
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, nm. I see it here.

final bool hasPackage = line.startsWith('package');
final RegExp parser = hasPackage
? RegExp(r'^(package:.+) (\d+):(\d+)\s+(.+)$')
? RegExp(r'^(package.+) (\d+):(\d+)\s+(.+)$')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a comment for this regexp. Separately, where would 'package' not be followed by ':' ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I filled a bug on it here with more details: #52685

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kk. Maybe link to that issue in a comment here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

);
}
} on Exception catch (err) {
globals.printError(err.toString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we can't give any more information here, and it will fail later regardless, should this just be a printTrace() ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented below

}
} on Exception catch (err) {
globals.printError(err.toString());
return OperationResult(1, err.toString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will including the err.toString() in the OperationResult case it to be printed twice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just updated here and above to be fatal errors, so we should print the message with a throwToolExit.

I can't think of a case where we hit a HotRestartException or WipError that we could recover from, so getting people out of the tool is likely better than getting stuck in a loop of prompting the user to "Try again after fixing the above error"

sdkRoot,
'--incremental',
'--target=$targetModel',
'--debugger-module-names',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any comments worth adding here about what this flag does?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment. This is a breaking change flag, so once all of the tooling is updated we can make it the default and remove

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an issue we can link to for the migration?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filled and linked #52693

.toList(),
workingDirectory: _projectFolder.path,
environment: <String, String>{'FLUTTER_TEST': 'true'},
environment: <String, String>{'FLUTTER_TEST': 'true', 'FLUTTER_WEB': 'true'},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider documenting here that this achieves the effect of flutter config --enable-web.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Member

@zanderso zanderso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. when this makes it to dev/, monitor crash logging for new crashers.

@jonahwilliams jonahwilliams merged commit 6884086 into flutter:master Mar 18, 2020
@jonahwilliams jonahwilliams deleted the devtools_stuff branch March 18, 2020 00:29
@lock
Copy link

lock bot commented Apr 2, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@lock lock bot locked and limited conversation to collaborators Apr 2, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

c: contributor-productivity Team-specific productivity, code health, technical debt. framework flutter/packages/flutter repository. See also f: labels. tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[web]: [macOS] [VSCode] Debugging broken in 1.15.2 and later

7 participants