Yurik has uploaded a new change for review.
https://gerrit.wikimedia.org/r/68869
Change subject: Ability to get partial result from the API
......................................................................
Ability to get partial result from the API
* Small memory devices seem to have issues with large JSON blobs.
This patch allows clients to request a portion of the text by
providing an offset and a maximum length.
* All "text" strings are virtually joined together, and only the
range after offset and no longer than maxlen is actually returned.
* A "continue-offset" value is set if there is more data.
Change-Id: Ib71800c1afa057bf87fd652ecb650bc38e33df68
---
M includes/api/ApiMobileView.php
1 file changed, 54 insertions(+), 3 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MobileFrontend
refs/changes/69/68869/1
diff --git a/includes/api/ApiMobileView.php b/includes/api/ApiMobileView.php
index a48cbd8..fe08f12 100644
--- a/includes/api/ApiMobileView.php
+++ b/includes/api/ApiMobileView.php
@@ -6,7 +6,8 @@
*/
const CACHE_VERSION = 3;
- private $followRedirects, $noHeadings, $mainPage, $noTransform,
$variant;
+ private $followRedirects, $noHeadings, $mainPage, $noTransform,
$variant, $offset, $maxlen;
+
/**
* @var File
*/
@@ -32,6 +33,14 @@
$this->followRedirects = $params['redirect'] == 'yes';
$this->noHeadings = $params['noheadings'];
$this->noTransform = $params['notransform'];
+ $this->offset = $params['offset'];
+ $this->maxlen = $params['maxlen'];
+
+ if ( $this->offset === 0 && $this->maxlen === 0 ) {
+ $this->offset = -1; // Disable text splitting
+ } elseif ( $this->maxlen === 0 ) {
+ $this->maxlen = PHP_INT_MAX;
+ }
$title = Title::newFromText( $params['page'] );
if ( !$title ) {
@@ -73,7 +82,7 @@
}
$section['id'] = $i;
if ( isset( $prop['text'] ) && isset(
$requestedSections[$i] ) && isset( $data['text'][$i] ) ) {
- $section[$textElement] =
$this->prepareSection( $data['text'][$i] );
+ $section[$textElement] =
$this->stringSplitter( $this->prepareSection( $data['text'][$i] ) );
unset( $requestedSections[$i] );
}
if ( isset( $data['refsections'][$i] ) ) {
@@ -86,7 +95,7 @@
foreach ( array_keys( $requestedSections ) as $index ) {
$section = array( 'id' => $index );
if ( isset( $data['text'][$index] ) ) {
- $section[$textElement] =
$data['text'][$index];
+ $section[$textElement] =
$this->stringSplitter( $data['text'][$index] );
} else {
$missingSections[] = $index;
}
@@ -96,9 +105,39 @@
if ( count( $missingSections ) && isset( $prop['text'] ) ) {
$this->setWarning( 'Section(s) ' . implode( ', ',
$missingSections ) . ' not found' );
}
+ if ( $this->maxlen < 0 ) {
+ // There is more data available
+ $this->getResult()->addValue( null,
$this->getModuleName(),
+ array( 'continue-offset' => $params['offset'] +
$params['maxlen'] )
+ );
+ }
$this->getResult()->setIndexedTagName( $result, 'section' );
$this->getResult()->addValue( null, $this->getModuleName(),
array( 'sections' => $result ) );
wfProfileOut( __METHOD__ );
+ }
+
+ private function stringSplitter( $text ) {
+ if ( $this->offset < 0 ) {
+ return $text; // NOOP - string splitting mode is off
+ } elseif ( $this->maxlen < 0 ) {
+ return ''; // Limit exceeded
+ }
+ $textLen = mb_strlen( $text );
+ $start = $this->offset;
+ $len = $textLen - $start;
+ if ( $len > 0 ) {
+ // At least part of the $text should be included
+ if ( $len > $this->maxlen ) {
+ $len = $this->maxlen;
+ $this->maxlen = -1;
+ } else {
+ $this->maxlen -= $len;
+ }
+ $this->offset = 0;
+ return mb_substr( $text, $start, $len );
+ }
+ $this->offset -= $textLen;
+ return '';
}
private function prepareSection( $html ) {
@@ -269,6 +308,16 @@
'noimages' => false,
'noheadings' => false,
'notransform' => false,
+ 'offset' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ApiBase::PARAM_MIN => 0,
+ ApiBase::PARAM_DFLT => 0,
+ ),
+ 'maxlen' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ApiBase::PARAM_MIN => 0,
+ ApiBase::PARAM_DFLT => 0,
+ ),
);
}
@@ -289,6 +338,8 @@
'noimages' => 'Return HTML without images',
'noheadings' => "Don't include headings in output",
'notransform' => "Don't transform HTML into
mobile-specific version",
+ 'offset' => 'Pretend all text result is one string, and
return the substring starting at this point',
+ 'maxlen' => 'Pretend all text result is one string, and
limit result to this length',
);
}
--
To view, visit https://gerrit.wikimedia.org/r/68869
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib71800c1afa057bf87fd652ecb650bc38e33df68
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Yurik <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits