GWicke has submitted this change and it was merged.
Change subject: TokenAccums: Handle push, append via receiveToksFromSibling.
......................................................................
TokenAccums: Handle push, append via receiveToksFromSibling.
* TokenAccumulator push and append were handled differently and
were adding tokens to the buffer which effectively treats them
as being received in 'waitForChild' state which is buggy because
the accum might have transitioned out of that state. This can
lead to tokens being lost since the buffer is ignored after the
accum exits the 'waitForChild' state.
* Fixed the bug by treating push and append methods as equivalent
to receiveToksFromSibling and using the tokens 'waitForSibling'
state as the async state for the receive.
* This bug fix fixes lost-token-errors in the chunky tokenizer
patch and eliminates the last of the async-related errors there.
* Left around from easy-debugging commented-out console.warn stmts.
which should help us quickly see how tokens are progressing through
the accum chains and cbs (at least helped me find this bug :-)).
* No change in parser test results.
* Verified errorless, diffless rting of en:Barack Obama.
Change-Id: I0400a941cb7a39d11072738681a5cce4587e82af
---
M js/lib/mediawiki.TokenTransformManager.js
1 file changed, 25 insertions(+), 9 deletions(-)
Approvals:
GWicke: Verified; Looks good to me, approved
jenkins-bot: Checked
diff --git a/js/lib/mediawiki.TokenTransformManager.js
b/js/lib/mediawiki.TokenTransformManager.js
index a13a612..e2cd36c 100644
--- a/js/lib/mediawiki.TokenTransformManager.js
+++ b/js/lib/mediawiki.TokenTransformManager.js
@@ -236,7 +236,9 @@
* @class
* @constructor
*/
+var auid = 0;
function AsyncTokenTransformManager ( env, options, pipeFactory, phaseEndRank,
attributeType ) {
+ this.uid = auid++; // useful for debugging
this.env = env;
this.options = options;
this.pipeFactory = pipeFactory;
@@ -313,6 +315,7 @@
try {
// Check if an EOFTk went missing
checkForEOFTkErrors(this, ret, !ret.async);
+ // console.warn("---> ATT-" + this.uid + " emit! " +
JSON.stringify(ret.tokens));
this.emit( 'chunk', ret.tokens );
if ( ret.async ) {
@@ -358,6 +361,7 @@
this.env.dp( 'emitting' );
this.emit( 'chunk', res.tokens );
} else {
+ // console.warn("--> ATT-" + this.uid + " appending: " +
JSON.stringify(res.tokens));
this.env.dp( 'appending to tail' );
this.tailAccumulator.append( res.tokens );
}
@@ -443,6 +447,7 @@
// that code path is exercised only when async mode is
entered,
// so we are all good on that front.
var newAccum = new TokenAccumulator( this.ttm, cb );
+ // 'newAccum' will receive tokens from a child
pipeline/cb
cbs.parentCB =
newAccum.receiveToksFromChild.bind(newAccum);
cbs.self = maybeAsyncCB;
@@ -466,7 +471,9 @@
this.state.res = {};
},
addNode: function() {
+ // console.warn("--> ATT-" + this.ttm.uid + " new link
in chain");
this.accum = this.next;
+ // 'accum' will receive toks from the 'next' node that
will be created
var nextAccumAndCB = this.makeNextAccum(
this.accum.receiveToksFromSibling.bind(this.accum) );
this.next = nextAccumAndCB.accum;
this.maybeAsyncCB = nextAccumAndCB.cb;
@@ -530,7 +537,7 @@
}
if (this.trace) {
- console.warn("A" + this.phaseEndRank + ": " +
JSON.stringify(token));
+ console.warn("A" + this.phaseEndRank + "-" + this.uid +
": " + JSON.stringify(token));
} else {
// SSS FIXME: with individual stage tracing, this
overall generic tracing
// is becoming less and less useful now. Do a cleanup
one of these days.
@@ -612,6 +619,7 @@
res.async = false;
}
+ // console.warn("--> ATT" +
this.uid + ": new work chunk" + JSON.stringify(resTokens));
workStack.pushChunk( resTokens
);
if (this.debug) {
@@ -644,6 +652,8 @@
}
}
}
+
+ // console.warn("--> ATT" + this.uid + ": chain sync processing done!");
// we are no longer transforming, maybeSyncReturn needs to follow the
// async code path
@@ -762,10 +772,6 @@
}
}
};
-
-
-
-
/*************** In-order, synchronous transformer (phase 1 and 3)
***************/
@@ -1107,7 +1113,9 @@
* @param {Object} next TokenAccumulator to link to
* @param {Array} (optional) tokens, init accumulator with tokens or []
*/
+var tid = 0;
function TokenAccumulator ( manager, parentCB ) {
+ this.uid = tid++; // useful for debugging
this.manager = manager;
this.parentCB = parentCB;
this.siblingToks = [];
@@ -1137,6 +1145,8 @@
this.siblingToks = [];
}
+ // console.warn("TA-" + this.uid + "; c: " + this.waitForChild + "; s:
" + this.waitForSibling + " <-- from child: " + JSON.stringify(ret));
+
ret.tokens.rank = this.manager.phaseEndRank;
ret.async = this.waitForSibling || this.waitForChild;
@@ -1159,6 +1169,8 @@
this.waitForSibling = false;
}
+ // console.warn("TA-" + this.uid + "; c: " + this.waitForChild + "; s:
" + this.waitForSibling + " <-- from sibling: " + JSON.stringify(ret));
+
if (this.waitForChild) {
// Just continue to accumulate sibling tokens.
this.siblingToks = this.siblingToks.concat( ret.tokens );
@@ -1173,6 +1185,7 @@
ret.tokens.rank = this.manager.phaseEndRank;
return this._callParentCB( ret );
} else {
+ // console.warn("TA-" + this.uid + " --ALL DONE!--");
// All done
ret.tokens = this.siblingToks.concat( ret.tokens );
ret.tokens.rank = this.manager.phaseEndRank;
@@ -1190,7 +1203,6 @@
this.receiveToksFromSibling( { tokens: [], async: false } );
};
-
TokenAccumulator.prototype._callParentCB = function ( ret ) {
var cb = this.parentCB( ret );
if ( cb ) {
@@ -1206,7 +1218,9 @@
* @param {Object} token
*/
TokenAccumulator.prototype.push = function ( token ) {
- return this.siblingToks.push(token);
+ // Treat a token push as a token-receive from a sibling
+ // in whatever async state the accum is currently in.
+ return this.receiveToksFromSibling({ tokens: [token], async:
this.waitForSibling });
};
/**
@@ -1215,8 +1229,10 @@
* @method
* @param {Object} token
*/
-TokenAccumulator.prototype.append = function ( token ) {
- this.siblingToks = this.siblingToks.concat( token );
+TokenAccumulator.prototype.append = function ( tokens ) {
+ // Treat tokens append as a token-receive from a sibling
+ // in whatever async state the accum is currently in.
+ return this.receiveToksFromSibling({ tokens: tokens, async:
this.waitForSibling });
};
--
To view, visit https://gerrit.wikimedia.org/r/49371
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I0400a941cb7a39d11072738681a5cce4587e82af
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Parsoid
Gerrit-Branch: master
Gerrit-Owner: Subramanya Sastry <[email protected]>
Gerrit-Reviewer: GWicke <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits