| Current File : /home/jvzmxxx/wiki1/extensions/EventLogging/includes/RemoteSchema.php |
<?php
/**
* Represents a schema revision on a remote wiki.
* Handles retrieval (via HTTP) and local caching.
*/
class RemoteSchema implements JsonSerializable {
const LOCK_TIMEOUT = 20;
public $title;
public $revision;
public $cache;
public $http;
public $key;
public $content = false;
/**
* Constructor.
* @param string $title
* @param integer $revision
* @param ObjectCache $cache (optional) cache client.
* @param Http $http (optional) HTTP client.
*/
public function __construct( $title, $revision, $cache = null, $http = null ) {
global $wgEventLoggingDBname;
$this->title = $title;
$this->revision = $revision;
$this->cache = $cache ?: wfGetCache( CACHE_ANYTHING );
$this->http = $http ?: new Http();
$this->key = "schema:{$wgEventLoggingDBname}:{$title}:{$revision}";
}
/**
* Retrieves schema content.
* @return array|bool: Schema or false if irretrievable.
*/
public function get() {
if ( $this->content ) {
return $this->content;
}
$this->content = $this->memcGet();
if ( $this->content ) {
return $this->content;
}
$this->content = $this->httpGet();
if ( $this->content ) {
$this->memcSet();
}
return $this->content;
}
/**
* Returns an object containing serializable properties.
*/
public function jsonSerialize() {
return [
'schema' => $this->get() ?: new stdClass(),
'revision' => $this->revision
];
}
/**
* Retrieves content from memcached.
* @return array:bool Schema or false if not in cache.
*/
protected function memcGet() {
return $this->cache->get( $this->key );
}
/**
* Store content in memcached.
*/
protected function memcSet() {
return $this->cache->set( $this->key, $this->content );
}
/**
* Retrieves the schema using HTTP.
* Uses a memcached lock to avoid cache stampedes.
* @return array|bool Schema or false if unable to fetch.
*/
protected function httpGet() {
if ( !$this->lock() ) {
return false;
}
$uri = $this->getUri();
$raw = $this->http->get( $uri, [
'timeout' => self::LOCK_TIMEOUT * 0.8
] );
$content = FormatJson::decode( $raw, true );
if ( !$content ) {
wfDebugLog( 'EventLogging', "Request to $uri failed." );
}
return $content ?: false;
}
/**
* Acquire a mutex lock for HTTP retrieval.
* @return bool Whether lock was successfully acquired.
*/
protected function lock() {
return $this->cache->add( $this->key . ':lock', 1, self::LOCK_TIMEOUT );
}
/**
* Constructs URI for retrieving schema from remote wiki.
* @return string URI.
*/
protected function getUri() {
global $wgEventLoggingSchemaApiUri;
return wfAppendQuery( $wgEventLoggingSchemaApiUri, [
'action' => 'jsonschema',
'revid' => $this->revision,
'formatversion' => 2,
] );
}
}