Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: pkg/barback/lib/src/graph/transform_node.dart

Issue 368463002: Automatically log how long each transform runs. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/barback/CHANGELOG.md ('k') | pkg/barback/lib/src/utils.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library barback.graph.transform_node; 5 library barback.graph.transform_node;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import '../asset/asset.dart'; 9 import '../asset/asset.dart';
10 import '../asset/asset_id.dart'; 10 import '../asset/asset_id.dart';
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 159
160 /// The controller for the currently-running [AggregateTransformer.apply] 160 /// The controller for the currently-running [AggregateTransformer.apply]
161 /// call's [AggregateTransform]. 161 /// call's [AggregateTransform].
162 /// 162 ///
163 /// This will be non-`null` when [AggregateTransform.apply] is running, which 163 /// This will be non-`null` when [AggregateTransform.apply] is running, which
164 /// means that it's always non-`null` when [_state] is [_State.APPLYING] or 164 /// means that it's always non-`null` when [_state] is [_State.APPLYING] or
165 /// [_State.NEEDS_APPLY], sometimes non-`null` when it's 165 /// [_State.NEEDS_APPLY], sometimes non-`null` when it's
166 /// [_State.NEEDS_DECLARE], and always `null` otherwise. 166 /// [_State.NEEDS_DECLARE], and always `null` otherwise.
167 AggregateTransformController _applyController; 167 AggregateTransformController _applyController;
168 168
169 /// The number of secondary inputs that have been requested but not yet
170 /// produced.
171 int _pendingSecondaryInputs = 0;
172
173 /// A stopwatch that tracks the total time spent in a transformer's `apply`
174 /// function.
175 final _timeInTransformer = new Stopwatch();
176
177 /// A stopwatch that tracks the time in a transformer's `apply` function spent
178 /// waiting for [getInput] calls to complete.
179 final _timeAwaitingInputs = new Stopwatch();
180
169 TransformNode(this.classifier, this.transformer, this.key, this._location) { 181 TransformNode(this.classifier, this.transformer, this.key, this._location) {
170 _forced = transformer is! DeclaringAggregateTransformer; 182 _forced = transformer is! DeclaringAggregateTransformer;
171 183
172 _phaseAssetSubscription = phase.previous.onAsset.listen((node) { 184 _phaseAssetSubscription = phase.previous.onAsset.listen((node) {
173 if (!_missingInputs.contains(node.id)) return; 185 if (!_missingInputs.contains(node.id)) return;
174 if (_forced) node.force(); 186 if (_forced) node.force();
175 _dirty(); 187 _dirty();
176 }); 188 });
177 189
178 _phaseStatusSubscription = phase.previous.onStatusChange.listen((status) { 190 _phaseStatusSubscription = phase.previous.onStatusChange.listen((status) {
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 553
542 _state = _State.APPLIED; 554 _state = _State.APPLIED;
543 _streams.changeStatus(NodeStatus.IDLE); 555 _streams.changeStatus(NodeStatus.IDLE);
544 }); 556 });
545 } 557 }
546 558
547 /// Gets the asset for an input [id]. 559 /// Gets the asset for an input [id].
548 /// 560 ///
549 /// If an input with [id] cannot be found, throws an [AssetNotFoundException]. 561 /// If an input with [id] cannot be found, throws an [AssetNotFoundException].
550 Future<Asset> getInput(AssetId id) { 562 Future<Asset> getInput(AssetId id) {
563 _timeAwaitingInputs.start();
564 _pendingSecondaryInputs++;
551 return phase.previous.getOutput(id).then((node) { 565 return phase.previous.getOutput(id).then((node) {
552 // Throw if the input isn't found. This ensures the transformer's apply 566 // Throw if the input isn't found. This ensures the transformer's apply
553 // is exited. We'll then catch this and report it through the proper 567 // is exited. We'll then catch this and report it through the proper
554 // results stream. 568 // results stream.
555 if (node == null) { 569 if (node == null) {
556 _missingInputs.add(id); 570 _missingInputs.add(id);
557 throw new AssetNotFoundException(id); 571 throw new AssetNotFoundException(id);
558 } 572 }
559 573
560 _secondarySubscriptions.putIfAbsent(node.id, () { 574 _secondarySubscriptions.putIfAbsent(node.id, () {
561 return node.onStateChange.listen((_) => _dirty()); 575 return node.onStateChange.listen((_) => _dirty());
562 }); 576 });
563 577
564 return node.asset; 578 return node.asset;
579 }).whenComplete(() {
580 _pendingSecondaryInputs--;
581 if (_pendingSecondaryInputs != 0) return;
Bob Nystrom 2014/07/01 17:08:35 Nit, but I think this is clearer without an early
nweiz 2014/07/01 21:57:09 Done.
582 _timeAwaitingInputs.stop();
565 }); 583 });
566 } 584 }
567 585
568 /// Run [AggregateTransformer.apply]. 586 /// Run [AggregateTransformer.apply].
569 /// 587 ///
570 /// Returns whether or not an error occurred while running the transformer. 588 /// Returns whether or not an error occurred while running the transformer.
571 Future<bool> _runApply() { 589 Future<bool> _runApply() {
572 var controller = new AggregateTransformController(this); 590 var controller = new AggregateTransformController(this);
573 _applyController = controller; 591 _applyController = controller;
574 _streams.onLogPool.add(controller.onLog); 592 _streams.onLogPool.add(controller.onLog);
575 for (var primary in _primaries) { 593 for (var primary in _primaries) {
576 if (!primary.state.isAvailable) continue; 594 if (!primary.state.isAvailable) continue;
577 controller.addInput(primary.asset); 595 controller.addInput(primary.asset);
578 } 596 }
579 _maybeFinishApplyController(); 597 _maybeFinishApplyController();
580 598
581 return syncFuture(() { 599 return syncFuture(() {
600 _timeInTransformer.reset();
601 _timeAwaitingInputs.reset();
602 _timeInTransformer.start();
582 return transformer.apply(controller.transform); 603 return transformer.apply(controller.transform);
583 }).whenComplete(() { 604 }).whenComplete(() {
605 _timeInTransformer.stop();
606 _timeAwaitingInputs.stop();
607
584 // Cancel the controller here even if `apply` wasn't interrupted. Since 608 // Cancel the controller here even if `apply` wasn't interrupted. Since
585 // the apply is finished, we want to close out the controller's streams. 609 // the apply is finished, we want to close out the controller's streams.
586 controller.cancel(); 610 controller.cancel();
587 _applyController = null; 611 _applyController = null;
588 }).then((_) { 612 }).then((_) {
589 assert(_state != _State.DECLARED); 613 assert(_state != _State.DECLARED);
590 assert(_state != _State.DECLARING); 614 assert(_state != _State.DECLARING);
591 assert(_state != _State.APPLIED); 615 assert(_state != _State.APPLIED);
592 616
593 if (!_forced && _primaries.any((node) => !node.state.isAvailable)) { 617 if (!_forced && _primaries.any((node) => !node.state.isAvailable)) {
594 _state = _State.DECLARED; 618 _state = _State.DECLARED;
595 _streams.changeStatus(NodeStatus.IDLE); 619 _streams.changeStatus(NodeStatus.IDLE);
596 return false; 620 return false;
597 } 621 }
598 622
599 if (_isRemoved) return false; 623 if (_isRemoved) return false;
600 if (_state == _State.NEEDS_APPLY) return false; 624 if (_state == _State.NEEDS_APPLY) return false;
601 if (_state == _State.NEEDS_DECLARE) return false; 625 if (_state == _State.NEEDS_DECLARE) return false;
602 if (controller.loggedError) return true; 626 if (controller.loggedError) return true;
627
628 // If the transformer took long enough, log its duration in fine output.
629 // That way it's not always visible, but users running with "pub serve
630 // --verbose" can see it.
Bob Nystrom 2014/07/01 17:08:36 Since it's at FINE anyway, how about either always
nweiz 2014/07/01 21:57:09 I added an additional check that compares the tota
631 if (_timeInTransformer.elapsed > new Duration(seconds: 1)) {
632 _streams.onLogController.add(new LogEntry(
633 info, info.primaryId, LogLevel.FINE,
634 "Took ${niceDuration(_timeInTransformer.elapsed)} "
Bob Nystrom 2014/07/01 17:08:36 Maybe clarify that it was apply() that was timed?
nweiz 2014/07/01 21:57:08 I think it's clear that that's what's going on.
635 "(${niceDuration(_timeAwaitingInputs.elapsed)} awaiting secondary "
Bob Nystrom 2014/07/01 17:08:35 Long line.
nweiz 2014/07/01 21:57:08 Done.
636 "inputs).",
637 null));
638 }
639
603 _handleApplyResults(controller); 640 _handleApplyResults(controller);
604 return false; 641 return false;
605 }).catchError((error, stackTrace) { 642 }).catchError((error, stackTrace) {
606 // If the transform became dirty while processing, ignore any errors from 643 // If the transform became dirty while processing, ignore any errors from
607 // it. 644 // it.
608 if (_state == _State.NEEDS_APPLY || _isRemoved) return false; 645 if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
609 646
610 // Catch all transformer errors and pipe them to the results stream. This 647 // Catch all transformer errors and pipe them to the results stream. This
611 // is so a broken transformer doesn't take down the whole graph. 648 // is so a broken transformer doesn't take down the whole graph.
612 phase.cascade.reportError(_wrapException(error, stackTrace)); 649 phase.cascade.reportError(_wrapException(error, stackTrace));
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 /// declaring and [APPLYING] otherwise. If a primary input is added or 833 /// declaring and [APPLYING] otherwise. If a primary input is added or
797 /// removed, this will transition to [DECLARING]. 834 /// removed, this will transition to [DECLARING].
798 static const APPLIED = const _State._("applied"); 835 static const APPLIED = const _State._("applied");
799 836
800 final String name; 837 final String name;
801 838
802 const _State._(this.name); 839 const _State._(this.name);
803 840
804 String toString() => name; 841 String toString() => name;
805 } 842 }
OLDNEW
« no previous file with comments | « pkg/barback/CHANGELOG.md ('k') | pkg/barback/lib/src/utils.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698