jenkins-bot has submitted this change and it was merged.
Change subject: Add a request timeout before the cpu timeout
......................................................................
Add a request timeout before the cpu timeout
Change-Id: If4a4208830fe0041994b5cfb9df5a87ef83c8807
---
M api/routes.js
1 file changed, 61 insertions(+), 43 deletions(-)
Approvals:
Subramanya Sastry: Looks good to me, approved
jenkins-bot: Verified
diff --git a/api/routes.js b/api/routes.js
index c7cd818..3214573 100644
--- a/api/routes.js
+++ b/api/routes.js
@@ -35,6 +35,16 @@
// Helpers
+// Should be less than the CPU_TIMEOUT
+var REQ_TIMEOUT = 4 * 60 * 1000; // 4 minutes
+function timeoutResp( env, err ) {
+ if ( err instanceof Promise.TimeoutError ) {
+ err = new Error("Request timed out.");
+ err.stack = null;
+ }
+ env.log("fatal/request", err);
+}
+
var CPU_TIMEOUT = 5 * 60 * 1000; // 5 minutes
var cpuTimeout = function( p, res ) {
return new Promise(function( resolve, reject ) {
@@ -72,6 +82,12 @@
}
});
});
+};
+
+var rtResponse = function( env, req, res, data ) {
+ apiUtils.setHeader( res, env, 'X-Parsoid-Performance',
env.getPerformanceHeader() );
+ apiUtils.renderResponse( res, env, "roundtrip", data );
+ env.log( "info", "completed parsing in", env.performance.duration, "ms"
);
};
var roundTripDiff = function( env, req, res, selser, doc ) {
@@ -115,19 +131,13 @@
var patch = Diff.convertChangesToXML( Diff.diffLines(src, out)
);
- apiUtils.setHeader(res, env, 'X-Parsoid-Performance',
env.getPerformanceHeader());
-
- apiUtils.renderResponse(res, env, "roundtrip", {
+ return {
headers: headNodes,
bodyNodes: bodyNodes,
htmlSpeChars: htmlSpeChars,
patch: patch,
reqUrl: req.url
- });
-
- env.log("info", "completed parsing in",
env.performance.duration, "ms");
- }).catch(function( err ) {
- env.log("fatal/request", err);
+ };
});
};
@@ -178,8 +188,6 @@
return Promise.promisify( pipeline.parse, false, pipeline )(
env, env.page.src, expansions
);
- }).catch(function( err ) {
- env.log("fatal/request", err);
});
};
@@ -191,7 +199,7 @@
// allow cross-domain requests (CORS) so that parsoid service
// can be used by third-party sites
apiUtils.setHeader(res, env, 'Access-Control-Allow-Origin',
- env.conf.parsoid.allowCORS );
+ env.conf.parsoid.allowCORS );
}
var out = [];
@@ -217,14 +225,13 @@
return Promise.promisify( serializer.serializeDOM, false,
serializer )(
doc.body, function( chunk ) { out.push( chunk ); },
false
);
- }).then(function() {
+ }).timeout( REQ_TIMEOUT ).then(function() {
apiUtils.setHeader(res, env, 'Content-Type', 'text/x-mediawiki;
charset=UTF-8');
apiUtils.setHeader(res, env, 'X-Parsoid-Performance',
env.getPerformanceHeader());
apiUtils.endResponse(res, env, out.join(''));
});
- return cpuTimeout(p, res).catch(function( err ) {
- env.log("fatal/request", err);
- });
+ return cpuTimeout( p, res )
+ .catch( timeoutResp.bind(null, env) );
};
var wt2html = function( req, res, wt, v2 ) {
@@ -275,20 +282,22 @@
resolve( doc );
});
parser.processToplevelDoc( wt );
- }).then( sendRes );
+ });
}
function parsePageWithOldid() {
- if ( !req.headers.cookie ) {
- apiUtils.setHeader(res, env, 'Cache-Control',
's-maxage=2592000');
- } else {
- // Don't cache requests with a session
- apiUtils.setHeader(res, env, 'Cache-Control',
'private,no-cache,s-maxage=0');
- }
- // Indicate the MediaWiki revision in a header as well for
- // ease of extraction in clients.
- apiUtils.setHeader(res, env, 'content-revision-id', oldid);
- return parse( env, req, res ).then( sendRes );
+ return parse( env, req, res ).then(function( doc ) {
+ if ( !req.headers.cookie ) {
+ apiUtils.setHeader(res, env, 'Cache-Control',
's-maxage=2592000');
+ } else {
+ // Don't cache requests with a session
+ apiUtils.setHeader(res, env, 'Cache-Control',
'private,no-cache,s-maxage=0');
+ }
+ // Indicate the MediaWiki revision in a header as well
for
+ // ease of extraction in clients.
+ apiUtils.setHeader(res, env, 'content-revision-id',
oldid);
+ return doc;
+ });
}
function redirectToOldid() {
@@ -328,16 +337,19 @@
}
if ( wt ) {
- p = p.then( parseWt );
+ p = p.then( parseWt )
+ .timeout( REQ_TIMEOUT )
+ .then(sendRes);
} else if ( oldid ) {
- p = p.then( parsePageWithOldid );
+ p = p.then( parsePageWithOldid )
+ .timeout( REQ_TIMEOUT )
+ .then(sendRes);
} else {
p = p.then( redirectToOldid );
}
- return cpuTimeout(p, res).catch(function( err ) {
- env.log("fatal/request", err);
- });
+ return cpuTimeout( p, res )
+ .catch( timeoutResp.bind(null, env) );
};
@@ -488,10 +500,12 @@
parse.bind( null, env, req, res )
).then(
roundTripDiff.bind( null, env, req, res, false )
+ ).timeout( REQ_TIMEOUT ).then(
+ rtResponse.bind( null, env, req, res )
);
- cpuTimeout(p, res).catch(function(err) {
- env.log("fatal/request", err);
- });
+
+ cpuTimeout( p, res )
+ .catch( timeoutResp.bind(null, env) );
};
// Round-trip article testing with newline stripping for editor-created HTML
@@ -511,10 +525,12 @@
// strip newlines from the html
var html = doc.innerHTML.replace(/[\r\n]/g, '');
return roundTripDiff( env, req, res, false, DU.parseHTML(html)
);
- });
- cpuTimeout(p, res).catch(function(err) {
- env.log("fatal/request", err);
- });
+ }).timeout( REQ_TIMEOUT ).then(
+ rtResponse.bind( null, env, req, res )
+ );
+
+ cpuTimeout( p, res )
+ .catch( timeoutResp.bind(null, env) );
};
// Round-trip article testing with selser over re-parsed HTML.
@@ -534,10 +550,12 @@
var comment = doc.createComment('rtSelserEditTestComment');
doc.body.appendChild(comment);
return roundTripDiff( env, req, res, true, doc );
- });
- cpuTimeout(p, res).catch(function(err) {
- env.log("fatal/request", err);
- });
+ }).timeout( REQ_TIMEOUT ).then(
+ rtResponse.bind( null, env, req, res )
+ );
+
+ cpuTimeout( p, res )
+ .catch( timeoutResp.bind(null, env) );
};
// Form-based round-tripping for manual testing
@@ -559,7 +577,7 @@
});
parse( env, req, res ).then(
roundTripDiff.bind( null, env, req, res, false )
- ).catch(function(err) {
+ ).then( rtResponse ).catch(function(err) {
env.log("fatal/request", err);
});
};
--
To view, visit https://gerrit.wikimedia.org/r/169297
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: If4a4208830fe0041994b5cfb9df5a87ef83c8807
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: Arlolra <[email protected]>
Gerrit-Reviewer: Arlolra <[email protected]>
Gerrit-Reviewer: Cscott <[email protected]>
Gerrit-Reviewer: Marcoil <[email protected]>
Gerrit-Reviewer: Subramanya Sastry <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits