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

Unified Diff: pkg/barback/lib/src/transform_node.dart

Issue 233843002: Don't make lazy transformers eager when an asset is requested. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: code review Created 6 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/barback/lib/src/asset_node.dart ('k') | pkg/barback/test/package_graph/lazy_transformer_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/barback/lib/src/transform_node.dart
diff --git a/pkg/barback/lib/src/transform_node.dart b/pkg/barback/lib/src/transform_node.dart
index 2269344d5eb0a3b2620761bd636e3df2fe712932..d27877b87aba846d80a64e59d1c543042fba94ea 100644
--- a/pkg/barback/lib/src/transform_node.dart
+++ b/pkg/barback/lib/src/transform_node.dart
@@ -45,14 +45,25 @@ class TransformNode {
StreamSubscription<AssetNode> _phaseSubscription;
/// Whether [this] is dirty and still has more processing to do.
- bool get isDirty => _state != _State.NOT_PRIMARY && _state != _State.APPLIED;
+ bool get isDirty => _state != _State.NOT_PRIMARY &&
+ _state != _State.APPLIED && _state != _State.DECLARED;
- /// Whether this transform is lazy and this transform has yet to be forced.
+ /// Whether this transform is deferred.
///
- /// A transform being lazy is distinct from a transformer being lazy. A
- /// transformer that's declaring but not lazy will have lazy transforms for
- /// primary inputs that are themselves lazy.
- bool _isLazy;
+ /// A transform is deferred if either its transformer is lazy or if its
+ /// transformer is declaring and its primary input comes from a deferred
+ /// transformer.
+ final bool deferred;
+
+ /// Whether this is a deferred transform waiting for [force] to be called to
+ /// generate inputs.
+ ///
+ /// This defaults to `true` for deferred transforms and `false` otherwise.
+ /// During or after running `isPrimary` or `declareOutputs`, this may become
+ /// `false`, indicating that the transform has been forced and should generate
+ /// outputs as soon as possible. It will only be set back to `true` if an
+ /// input changes *after* `apply` has completed.
+ bool _awaitingForce;
/// The subscriptions to each input's [AssetNode.onStateChange] stream.
final _inputSubscriptions = new Map<AssetId, StreamSubscription>();
@@ -100,7 +111,7 @@ class TransformNode {
final _onLogController = new StreamController<LogEntry>.broadcast(sync: true);
/// The current state of [this].
- var _state = _State.COMPUTING_IS_PRIMARY;
+ var _state = _State.DECLARING;
/// Whether [this] has been marked as removed.
bool get _isRemoved => _onAssetController.isClosed;
@@ -109,7 +120,7 @@ class TransformNode {
/// consumes the primary input.
///
/// Defaults to `false`. This is not meaningful unless [_state] is
- /// [_State.APPLIED].
+ /// [_State.APPLIED] or [_State.DECLARED].
bool _consumePrimary = false;
/// The set of output ids that [transformer] declared it would emit.
@@ -122,22 +133,29 @@ class TransformNode {
this._location)
: transformer = transformer,
primary = primary,
- _isLazy = transformer is LazyTransformer ||
- (transformer is DeclaringTransformer && primary.isLazy) {
+ deferred = transformer is LazyTransformer ||
+ (transformer is DeclaringTransformer &&
+ primary.transform != null &&
+ primary.transform.deferred) {
Bob Nystrom 2014/04/14 19:20:25 Instead of checking for a null transform here, wha
nweiz 2014/04/14 21:55:07 Done.
+ _awaitingForce = deferred;
+
_onLogPool.add(_onLogController.stream);
- if (!_isLazy) primary.force();
+ if (!deferred) primary.force();
_primarySubscription = primary.onStateChange.listen((state) {
if (state.isRemoved) {
remove();
} else {
+ if (state.isDirty && !deferred) primary.force();
_dirty();
}
});
_phaseSubscription = phase.previous.onAsset.listen((node) {
- if (_missingInputs.contains(node.id)) _dirty();
+ if (!_missingInputs.contains(node.id)) return;
+ if (!deferred) node.force();
+ _dirty();
});
_isPrimary();
@@ -169,14 +187,12 @@ class TransformNode {
}
}
- /// If [transformer] is lazy, ensures that its concrete outputs will be
+ /// If [this] is deferred, ensures that its concrete outputs will be
/// generated.
void force() {
- // TODO(nweiz): we might want to have a timeout after which, if the
- // transform's outputs have gone unused, we switch it back to lazy mode.
- if (!_isLazy) return;
+ if (!_awaitingForce) return;
primary.force();
- _isLazy = false;
+ _awaitingForce = false;
_dirty();
}
@@ -188,14 +204,38 @@ class TransformNode {
_emitPassThrough();
return;
}
- if (_state == _State.COMPUTING_IS_PRIMARY || _isLazy) return;
+
+ // If we're in the process of running [isPrimary] or [declareOutputs], we're
Bob Nystrom 2014/04/14 19:20:25 "we're" -> "we"
nweiz 2014/04/14 21:55:07 Done.
+ // already know that [apply] needs to be run so there's nothing we need to
+ // mark as dirty.
+ if (_state == _State.DECLARING) return;
+
+ // If we're waiting until [force] is called to run [apply], we don't to run
Bob Nystrom 2014/04/14 19:20:25 "don't to" -> "don't want to".
nweiz 2014/04/14 21:55:07 Done.
+ // [apply] too early.
+ if (_awaitingForce) return;
+
+ if (_state == _State.APPLIED && deferred) {
+ // Transition to DECLARED, indicating that we know what outputs [apply]
+ // will emit but we're waiting to emit them concretely until [force] is
+ // called.
+ _state = _State.DECLARED;
+ _awaitingForce = true;
+ for (var controller in _outputControllers.values) {
+ controller.setLazy(force);
+ }
+ return;
+ }
if (_passThroughController != null) _passThroughController.setDirty();
for (var controller in _outputControllers.values) {
- controller.setDirty();
+ // Don't re-mark a controller as dirty to avoid cases where we try to
+ // dispatch an event while handling another event (e.g. an output is
+ // marked lazy, which causes it to be forced, which causes it to be marked
+ // dirty).
+ if (!controller.node.state.isDirty) controller.setDirty();
Bob Nystrom 2014/04/14 19:20:25 Can this check be moved into .setDirty()?
nweiz 2014/04/14 21:55:07 Done.
}
- if (_state == _State.APPLIED) {
+ if (_state == _State.APPLIED || _state == _State.DECLARED) {
_apply();
} else {
_state = _State.NEEDS_APPLY;
@@ -221,8 +261,8 @@ class TransformNode {
if (isPrimary) {
return _declareOutputs().then((_) {
if (_isRemoved) return;
- if (_isLazy) {
- _state = _State.APPLIED;
+ if (_awaitingForce) {
+ _state = _State.DECLARED;
_onDoneController.add(null);
} else {
_apply();
@@ -262,7 +302,7 @@ class TransformNode {
if (!_declaredOutputs.contains(primary.id)) _emitPassThrough();
for (var id in _declaredOutputs) {
- var controller = _isLazy
+ var controller = _awaitingForce
? new AssetNodeController.lazy(id, force, this)
: new AssetNodeController(id, this);
_outputControllers[id] = controller;
@@ -276,7 +316,7 @@ class TransformNode {
/// Applies this transform.
void _apply() {
- assert(!_isRemoved && !_isLazy);
+ assert(!_isRemoved && !_awaitingForce);
// Clear input subscriptions here as well as in [_process] because [_apply]
// may be restarted independently if only a secondary input changes.
@@ -324,7 +364,7 @@ class TransformNode {
}
_inputSubscriptions.putIfAbsent(node.id, () {
- return node.onStateChange.listen((_) => _dirty());
+ return node.onStateChange.listen((state) => _dirty());
});
return node.asset;
@@ -475,12 +515,22 @@ class TransformNode {
/// The enum of states that [TransformNode] can be in.
class _State {
- /// The transform is running [Transformer.isPrimary].
+ /// The transform is running [Transformer.isPrimary] followed by
+ /// [DeclaringTransformer.declareOutputs] (for a [DeclaringTransformer]).
+ ///
+ /// This is the initial state of the transformer, and it will only occur once
+ /// since [Transformer.isPrimary] and [DeclaringTransformer.declareOutputs]
+ /// are independent of the contents of the primary input. Once the two methods
+ /// finish running, this will transition to [NOT_PRIMARY] if the input isn't
+ /// primary, [DECLARED] if the transform is deferred, and [APPLYING] otherwise.
Bob Nystrom 2014/04/14 19:20:25 Long line.
nweiz 2014/04/14 21:55:07 Done.
+ static final DECLARING = const _State._("computing isPrimary");
+
+ /// The transform is deferred and has run [DeclaringTransformer.declareOutputs]
+ /// but hasn't yet been forced.
///
- /// This is the initial state of the transformer. Once [Transformer.isPrimary]
- /// finishes running, this will transition to [APPLYING] if the input is
- /// primary, or [NOT_PRIMARY] if it's not.
- static final COMPUTING_IS_PRIMARY = const _State._("computing isPrimary");
+ /// This will transition to [APPLYING] when one of the outputs has been
+ /// forced.
+ static final DECLARED = const _State._("declared");
/// The transform is running [Transformer.apply].
///
@@ -499,11 +549,12 @@ class _State {
/// The transform has finished running [Transformer.apply], whether or not it
/// emitted an error.
///
- /// If the transformer is lazy, the [TransformNode] can also be in this state
- /// when [Transformer.declareOutputs] has been run but [Transformer.apply] has
- /// not.
+ /// If the transformer is deferred, the [TransformNode] can also be in this
+ /// state when [Transformer.declareOutputs] has been run but
+ /// [Transformer.apply] has not.
///
- /// If an input changes, this will transition to [APPLYING].
+ /// If an input changes, this will transition to [DECLARED] if the transform
+ /// is deferred and [APPLYING] otherwise.
static final APPLIED = const _State._("applied");
/// The transform has finished running [Transformer.isPrimary], which returned
« no previous file with comments | « pkg/barback/lib/src/asset_node.dart ('k') | pkg/barback/test/package_graph/lazy_transformer_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698