Skip to content

Emit useful information about build results #1710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 7, 2018
Merged

Conversation

samogot
Copy link
Contributor

@samogot samogot commented Aug 4, 2018

Instead of just 'update' emit json with updated build results and its
digests

Instead of just 'update' emit json with updated build results and its
digests
@googlebot googlebot added the cla: yes Google is happy with the PR contributors label Aug 4, 2018
@samogot samogot requested review from jakemac53 and natebosch August 4, 2018 01:37
@samogot
Copy link
Contributor Author

samogot commented Aug 4, 2018

To find a way how to pass rootDir correctly was really hard. I was surprised that we can serve several different root dirs at the same time reusing the same handler (https://github.com/dart-lang/build/blob/hot-reload/build_runner/lib/src/entrypoint/serve.dart#L75). I wonder why we need several root dirs?

String assetIdToPath(AssetId assetId, String rootDir) =>
assetId.path.startsWith('lib/')
? assetId.path.replaceFirst('lib/', 'packages/${assetId.package}/')
: assetId.path.replaceFirst('${rootDir}/', '');
Copy link
Member

Choose a reason for hiding this comment

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

Is this triggering a lint?

- unnecessary_brace_in_string_interps

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, this doesn't compile without this braces. I don't understand why exactly, but looks like / is also tried to be interpreted somehow

Copy link
Member

Choose a reason for hiding this comment

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

I can't repro - what is the exact error you see?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, it works now. Looks like it was some weird error while trying different things.

for (var webSocket in activeConnections) {
webSocket.sink.add(_buildUpdatesMessage);
Future emitUpdateMessage(BuildResult buildResult) async {
if (buildResult.status == BuildStatus.success) {
Copy link
Member

Choose a reason for hiding this comment

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

[optional] Consider reversing the condition and bailing out early instead of nesting the entire method mode an extra level.

if (buildResult.status == BuildStatus.success) return;
var digests = <AssetId, String>{};
...

webSocket.sink.add(_buildUpdatesMessage);
Future emitUpdateMessage(BuildResult buildResult) async {
if (buildResult.status == BuildStatus.success) {
var digestMap = <AssetId, String>{};
Copy link
Member

Choose a reason for hiding this comment

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

[nit] how about digests or digestById? We typically avoid putting the collection type in the variable names.

var digest = await _state.reader.digest(assetId);
digestMap[assetId] = digest.toString();
}
for (var con in activeConnections) {
Copy link
Member

Choose a reason for hiding this comment

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

[nit] avoid the abbreviation, for (var connection in activeConnections)

var path = assetIdToPath(assetId, con.rootDir);
resultMap[path] = digestMap[assetId];
}
con.webSocket.sink.add(jsonEncode(resultMap));
Copy link
Member

Choose a reason for hiding this comment

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

this could be relatively big right? Should we worry about that?

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 was more worried about body of request in other PR, and @jakemac53 said that it's ok.

@@ -123,36 +126,62 @@ class ServeHandler implements BuildState {
}
}

class _ConnectionInfo {
Copy link
Member

Choose a reason for hiding this comment

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

how about _Connection. Info doesn't add new value

for (var con in activeConnections) {
var resultMap = <String, String>{};
for (var assetId in digestMap.keys) {
var path = assetIdToPath(assetId, con.rootDir);
Copy link
Contributor

Choose a reason for hiding this comment

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

Any asset not under con.rootDir or the lib dir can't be referenced anyways so we should skip them here.

String assetIdToPath(AssetId assetId, String rootDir) =>
assetId.path.startsWith('lib/')
? assetId.path.replaceFirst('lib/', 'packages/${assetId.package}/')
: assetId.path.replaceFirst('${rootDir}/', '');
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to my comment below, but if it doesn't start with $rootDir or lib then we can't produce a valid path. This function could either throw or return null to indicate that, and we should document which it does.

- Filter out inaccessible paths
- Group connections by root dir
- Update shelf_web_socket module
await clientChannel1.sink.close();
});

test('emmits only on sussesful builds', () async {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: successful

BuildUpdatesWebSocketHandler(this._state,
[this._handlerFactory = webSocketHandler]) {}

shelf.Handler getHandlerByRootDir(String rootDir) {
Copy link
Member

Choose a reason for hiding this comment

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

BuildUpdatesWebSocketHandler buildUpdatesWebSocketHandler;
Function createMockConection;
BuildUpdatesWebSocketHandler handler;
Future<Null> Function(WebSocketChannel, String) createMockConnection;
Copy link
Member

Choose a reason for hiding this comment

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

[nit] Prefer Future<void> over Future<Null>. The reason you see Future<Null> in so much existing code is void used to not work there, but now that it does it's our preference for new code

@samogot samogot merged commit e3a4fae into hot-reload Aug 7, 2018
@samogot samogot deleted the emit-build-results branch August 7, 2018 23:21
samogot added a commit that referenced this pull request Aug 28, 2018
* Add assets digests handler (#1709)

This entry point will be used for hot reloading, in order to initially
retrieve digests of all assets, as build_runner might not know list of
all of them, unlike client.

* Emit useful information about build results (#1710)

Instead of just 'update' emit json with updated build results and its
digests

* Move live reload client code to new hot_reload_client.dart file (#1732)

It is expected that client code will become complicated, so in separate
dart file it would be easier to test and maintain.

* Implement basic hot reload (#1741)

Reload any changed modules without any specific order, then reload main
module and call main func to hopefully apply changes.

Still need to get module dependency graph to reload in topological order
and find correct ancessor chain where reloaded modules can be saved in
closures.

* Basic graph handling for hot reload (#1759)

We still lack handling situations when graph is dynamically updated
between reloads.

* Add rough graph changes handling by full page reload (#1763)

* Simplify module interface (#1764)

* Change HMR API to work with several libraries bundled in one module (#1765)

Fixes #1762

* Close Hot Reload listeners on exit (#1775)

Closes #1774

* Refactor and improve HMR code (#1770)

- Get rid of `roughLibraryKeyDecode` - use library path exposed from
  dart runtime now.
- Get load modules from cache directly and throw if it isn't loaded
  instead of using require.js and hoping that module already loaded and
  no network request would be done.
- Don't mess with `.ddc` extension in `build_runner` code - encapsulate
  all of it on build_web_compilers side.

Fixes #1760
Fixes #1762

* Finalize hot-reloading feature (#1773)

- Rename live-reload to hot-reload
- Add debug logging about reloading
- Add documentation
- Version bump and changelog

Fixes #1766

* Restore --live-reload option (#1778)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Google is happy with the PR contributors
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants