Catrope has uploaded a new change for review.
https://gerrit.wikimedia.org/r/93109
Change subject: Implement serialization cache in VisualEditor API
......................................................................
Implement serialization cache in VisualEditor API
Add paction=serializeforcache, which serializes the given HTML, stores
the resulting wikitext in memcached, and returns a cache key. This
cache key can then be passed instead of HTML to paction=diff or
action=visualeditoredit for quick diff/save operations using the
cached wikitext, or to paction=serialize to just retrieve the wikitext.
This lays the groundwork for predictive serialization in the editor,
and for avoiding the double serialization that occurs when the user
first views the diff, then saves.
Change-Id: I223b1717890632c39e2509967149551f807119f8
---
M ApiVisualEditor.php
M ApiVisualEditorEdit.php
M VisualEditor.php
3 files changed, 68 insertions(+), 18 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor
refs/changes/09/93109/1
diff --git a/ApiVisualEditor.php b/ApiVisualEditor.php
index 33079c9..e8f0fab 100644
--- a/ApiVisualEditor.php
+++ b/ApiVisualEditor.php
@@ -95,6 +95,24 @@
);
}
+ protected function storeInSerializationCache( $title, $oldid, $html ) {
+ global $wgMemc, $wgVisualEditorSerializationCacheTimeout;
+ $hash = md5( $title . '|' . $oldid . '|' . $html );
+ $key = wfMemcKey( 'visualeditor', 'serialization', $hash );
+ $content = $this->postHTML( $title, $html, array( 'oldid' =>
$oldid ) );
+ if ( $content === false ) {
+ return false;
+ }
+ $wgMemc->set( $key, $content,
$wgVisualEditorSerializationCacheTimeout );
+ return $hash;
+ }
+
+ protected function trySerializationCache( $hash ) {
+ global $wgMemc;
+ $key = wfMemcKey( 'visualeditor', 'serialization', $hash );
+ return $wgMemc->get( $key );
+ }
+
protected function postHTML( $title, $html, $parserParams ) {
global $wgVisualEditorParsoidURL, $wgVisualEditorParsoidPrefix,
$wgVisualEditorParsoidTimeout;
@@ -296,21 +314,34 @@
}
break;
case 'serialize':
- if ( $params['html'] === null ) {
- $this->dieUsageMsg( 'missingparam',
'html' );
- }
- $content = $this->postHTML( $page,
$params['html'], $parserParams );
- if ( $content === false ) {
- $this->dieUsage( 'Error contacting the
Parsoid server', 'parsoidserver' );
+ if ( $params['cachekey'] !== null ) {
+ $content =
$this->trySerializationCache( $params['cachekey'] );
+ if ( !is_string( $content ) ) {
+ $this->dieUsage( 'No cached
serialization found with that key', 'badcachekey' );
+ }
} else {
- $result = array( 'result' => 'success',
'content' => $content );
+ if ( $params['html'] === null ) {
+ $this->dieUsageMsg(
'missingparam', 'html' );
+ }
+ $html = $params['html'];
+ $content = $this->postHTML( $page,
$html, $parserParams );
+ if ( $content === false ) {
+ $this->dieUsage( 'Error
contacting the Parsoid server', 'parsoidserver' );
+ }
}
+ $result = array( 'result' => 'success',
'content' => $content );
break;
case 'diff':
- $wikitext = $this->postHTML( $page,
$params['html'], $parserParams );
-
- if ( $wikitext === false ) {
- $this->dieUsage( 'Error contacting the
Parsoid server', 'parsoidserver' );
+ if ( $params['cachekey'] !== null ) {
+ $wikitext =
$this->trySerializationCache( $params['cachekey'] );
+ if ( !is_string( $wikitext ) ) {
+ $this->dieUsage( 'No cached
serialization found with that key', 'badcachekey' );
+ }
+ } else {
+ $wikitext = $this->postHTML( $page,
$params['html'], $parserParams );
+ if ( $wikitext === false ) {
+ $this->dieUsage( 'Error
contacting the Parsoid server', 'parsoidserver' );
+ }
}
$diff = $this->diffWikitext( $page, $wikitext );
@@ -319,6 +350,10 @@
}
$result = $diff;
+ break;
+ case 'serializeforcache':
+ $key = $this->storeInSerializationCache( $page,
$parserParams['oldid'], $params['html'] );
+ $result = array( 'result' => 'success',
'cachekey' => $key );
break;
}
@@ -332,13 +367,14 @@
),
'paction' => array(
ApiBase::PARAM_REQUIRED => true,
- ApiBase::PARAM_TYPE => array( 'parse',
'parsefragment', 'serialize', 'diff' ),
+ ApiBase::PARAM_TYPE => array( 'parse',
'parsefragment', 'serializeforcache', 'serialize', 'diff' ),
),
'wikitext' => null,
'basetimestamp' => null,
'starttimestamp' => null,
'oldid' => null,
'html' => null,
+ 'cachekey' => null,
);
}
@@ -365,9 +401,11 @@
'oldid' => 'The revision number to use (defaults to
latest version).',
'html' => 'HTML to send to parsoid in exchange for
wikitext',
'basetimestamp' => 'When saving, set this to the
timestamp of the revision that was'
- .' edited. Used to detect edit conflicts.',
+ . ' edited. Used to detect edit conflicts.',
'starttimestamp' => 'When saving, set this to the
timestamp of when the page was loaded.'
- .' Used to detect edit conflicts.',
+ . ' Used to detect edit conflicts.',
+ 'cachekey' => 'For serialize or diff, use the result of
a previous serializeforcache'
+ . ' request with this key. Overrides html.',
);
}
diff --git a/ApiVisualEditorEdit.php b/ApiVisualEditorEdit.php
index d552d05..7ab50fb 100644
--- a/ApiVisualEditorEdit.php
+++ b/ApiVisualEditorEdit.php
@@ -71,10 +71,16 @@
$parserParams['oldid'] = $params['oldid'];
}
- $wikitext = $this->postHTML( $page, $params['html'],
$parserParams );
-
- if ( $wikitext === false ) {
- $this->dieUsage( 'Error contacting the Parsoid server',
'parsoidserver' );
+ if ( $params['cachekey'] !== null ) {
+ $wikitext = $this->trySerializationCache(
$params['cachekey'] );
+ if ( !is_string( $wikitext ) ) {
+ $this->dieUsage( 'No cached serialization found
with that key', 'badcachekey' );
+ }
+ } else {
+ $wikitext = $this->postHTML( $page, $params['html'],
$parserParams );
+ if ( $wikitext === false ) {
+ $this->dieUsage( 'Error contacting the Parsoid
server', 'parsoidserver' );
+ }
}
$saveresult = $this->saveWikitext( $page, $wikitext, $params );
@@ -140,6 +146,7 @@
'summary' => null,
'captchaid' => null,
'captchaword' => null,
+ 'cachekey' => null,
);
}
@@ -175,6 +182,8 @@
. ' problems. This will result in the edit
being tagged.',
'captchaid' => 'Captcha ID (when saving with a captcha
response).',
'captchaword' => 'Answer to the captcha (when saving
with a captcha response).',
+ 'cachekey' => 'Use the result of a previous
serializeforcache request with this key.'
+ . 'Overrides html.',
);
}
diff --git a/VisualEditor.php b/VisualEditor.php
index 76fa84a..e8eda10 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -883,6 +883,9 @@
// Timeout for HTTP requests to Parsoid in seconds
$wgVisualEditorParsoidTimeout = 100;
+// Serialization cache timeout, in seconds
+$wgVisualEditorSerializationCacheTimeout = 3600;
+
// Namespaces to enable VisualEditor in
$wgVisualEditorNamespaces = $wgContentNamespaces;
--
To view, visit https://gerrit.wikimedia.org/r/93109
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I223b1717890632c39e2509967149551f807119f8
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Catrope <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits