Skip to content

Conversation

@xster
Copy link
Member

@xster xster commented Apr 25, 2017

  • Create a generic FlutterCommandResult plumbing for FlutterCommand subclasses to pipe back analytics messages
  • Instead of recording the entire resident runner session, record the app speed of flutter run to the app start
  • Record flutter run success/fail, build mode, hot/cold, platform, emulator.

Fixes #9500
Fixes #9499
Fixes #9498

@xster xster requested review from danrubel and devoncarew April 25, 2017 23:45
@xster xster changed the title Record flutter run success/fail, build mode, start time in analytics Record flutter run success/fail, build mode, platform, start time in analytics Apr 26, 2017
@xster xster requested a review from tvolkert April 26, 2017 02:19
@xster
Copy link
Member Author

xster commented Apr 26, 2017

Added a clock to the testing context

Copy link
Contributor

@tvolkert tvolkert left a comment

Choose a reason for hiding this comment

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

Travis and AppVeyor seem unhappy.

Copy link
Contributor

Choose a reason for hiding this comment

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

Chaining the .. with the .then() makes this hard to immediately grok - maybe split it into distinct statements?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

The formatting style for this is:

FlutterCommandResult(
  this.exitCode, {
  this.analyticsParameters,
  this.exitTime,
}) {
  assert(exitCode != null);
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok

Copy link
Contributor

Choose a reason for hiding this comment

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

final on all three of these.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: newline between field declarations.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe explain that FlutterCommand is what's doing the measurement so the reader knows where this automatic calculation will be made. Something like "If this is not provided, [FlutterCommand] will default to the command's completion time when calculating the command's running time"

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a use case for commands providing their own entry time as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

No. I think we should measure user perceivable time. That latency measurement should start as early as possible.

Copy link
Contributor

Choose a reason for hiding this comment

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

By starting this here, we'll record the time it takes to update the cache if needed (which is done in verifyThenRunCommand()), which will mess with the analytics results...

Copy link
Member Author

Choose a reason for hiding this comment

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

Ditto. I think that's fine as a metric to optimize for.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is this used anymore? It looks like UsageTimer can be nuked.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done. Love deleting code

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you mean MockClock (or FakeClock given my comment below)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah ya. I was gonna switch everything without breaking the existing tests but there were too many. Done. We can swap the others as needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's such a simple interface, it may be worth writing a FakeClock and saving your tests the effort of mocking... It could have a setter for setting the current time, and it'd increment the value every time now() was called.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's ok for the test to be verbose wrt the input/output near the assertions.

Copy link
Contributor

Choose a reason for hiding this comment

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

endTime? endTimeOverride?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure. Renamed to endTimeOverride

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I think flutter style would want single quotes here

Copy link
Member Author

Choose a reason for hiding this comment

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

ah thanks

Copy link
Contributor

Choose a reason for hiding this comment

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

There's a utility to print ms - getElapsedAsMilliseconds(Duration). Generally used for user facing output (non-trace output), but perhap useful here.

Copy link
Member Author

Choose a reason for hiding this comment

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

oh cool, thanks

Copy link
Contributor

Choose a reason for hiding this comment

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

you don't need the await here, since you're now returning the Future

Copy link
Contributor

Choose a reason for hiding this comment

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

I've heard that while the VM unwraps futures in these cases, it's bad style, but then I've also heard it's fiiiine. @abarth or @Hixie, is there a definitive answer?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think semantically, we don't need to await here

Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: for _ parameters, you can omit the type.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused as to what this is trying to do. Wouldn't scheduleMicrotask do the same thing cleanly? Or Future.sync?

Copy link
Member Author

Choose a reason for hiding this comment

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

oh cool, thanks

Copy link
Member Author

Choose a reason for hiding this comment

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

oops, our comments crossed paths midair.

I didn't really understand the references to Future in the Completer's dartdoc either. It seems to be written for the perspective of the Completer's reader rather than the Completer's supplier.

I'm trying to supply a Completer such that a piece of code runs synchronously when the owner of the Completer, a few layers deeper, calls complete() on it.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure what "supply a completer" means. Normally a completer is private to the person who creates it, and you hand out its future.

Copy link
Contributor

Choose a reason for hiding this comment

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

@Hixie I had the same reaction, but it looks like it's an existing API in tools. I plan to remedy this in a separate PR by having the caller pass a callback instead of a completer.

Copy link
Member Author

Choose a reason for hiding this comment

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

cool neat. It doesn't actually seem heavily used in the codebase. A simpler callback would indeed be easier to parse.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you're synced to tip-of-tree, this now needs to be await device.targetPlatform

Copy link
Member Author

Choose a reason for hiding this comment

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

thanks

Copy link
Contributor

Choose a reason for hiding this comment

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

Likewise, await device.isLocalEmulator

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

Choose a reason for hiding this comment

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

No need for the ? here

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

Choose a reason for hiding this comment

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

Similar formatting comment here:

  Duration duration, {
  String label,

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

Choose a reason for hiding this comment

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

We used to check for suppressAnalytics...

Copy link
Member Author

Choose a reason for hiding this comment

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

nice catch, thanks!

Copy link
Contributor

Choose a reason for hiding this comment

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

MockUsage and MockClock are seeded in the context for tests by default, so you don't need to instantiate and override them here. (same comment in the tests below)

Copy link
Member Author

Choose a reason for hiding this comment

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

so I ended up defaulting back to a real clock. I think it's more convenient as we move more and more stuff to Clock for tests that don't really care to keep working without null handling and not get an arbitrary value.

@xster
Copy link
Member Author

xster commented Apr 26, 2017

Ah, I was wondering why travis was failing. Rebased.

Also TIL quiver. Removed Clock since there already is one and used some of the string functions

String label,
}) {
if (!suppressAnalytics) {
_analytics.sendTiming(
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: indent

@xster xster merged commit 66ed8de into flutter:master Apr 27, 2017
@xster xster deleted the analytics branch April 27, 2017 22:28
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Record flutter run debug/profile/release Record flutter run success/failure Run user timing analytic should measure time to connect

5 participants