jenkins-bot has submitted this change and it was merged.

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 front-loading serialization in the editor,
and for avoiding the double serialization that occurs when the user
first views the diff, then saves.


Bug: 55979
Bug: 56011
Change-Id: I223b1717890632c39e2509967149551f807119f8
---
M ApiVisualEditor.php
M ApiVisualEditorEdit.php
M VisualEditor.php
3 files changed, 70 insertions(+), 18 deletions(-)

Approvals:
  Esanders: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/ApiVisualEditor.php b/ApiVisualEditor.php
index 729988b..89de31a 100644
--- a/ApiVisualEditor.php
+++ b/ApiVisualEditor.php
@@ -99,6 +99,24 @@
                );
        }
 
+       protected function storeInSerializationCache( $title, $oldid, $html ) {
+               global $wgMemc, $wgVisualEditorSerializationCacheTimeout;
+               $content = $this->postHTML( $title, $html, array( 'oldid' => 
$oldid ) );
+               if ( $content === false ) {
+                       return false;
+               }
+               $hash = md5( $content );
+               $key = wfMemcKey( 'visualeditor', 'serialization', $hash );
+               $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, 
$wgVisualEditorParsoidForwardCookies;
@@ -312,21 +330,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 );
@@ -335,6 +366,10 @@
                                }
                                $result = $diff;
 
+                               break;
+                       case 'serializeforcache':
+                               $key = $this->storeInSerializationCache( $page, 
$parserParams['oldid'], $params['html'] );
+                               $result = array( 'result' => 'success', 
'cachekey' => $key );
                                break;
                }
 
@@ -348,13 +383,16 @@
                        ),
                        '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,
                );
        }
 
@@ -381,9 +419,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 a5e8454..e6c65a5 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -896,6 +896,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: merged
Gerrit-Change-Id: I223b1717890632c39e2509967149551f807119f8
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Catrope <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Hashar <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to