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

Reply via email to