MediaWiki master
ExternalStoreMwstore.php
Go to the documentation of this file.
1<?php
8
9use InvalidArgumentException;
15
29 private $fbGroup;
30
36 public function __construct( array $params ) {
37 parent::__construct( $params );
38 if ( !isset( $params['fbGroup'] ) || !( $params['fbGroup'] instanceof FileBackendGroup ) ) {
39 throw new InvalidArgumentException( "FileBackendGroup required in 'fbGroup' field." );
40 }
41 $this->fbGroup = $params['fbGroup'];
42 }
43
51 public function fetchFromURL( $url ) {
52 $be = $this->fbGroup->backendFromPath( $url );
53 if ( $be instanceof FileBackend ) {
54 // We don't need "latest" since objects are immutable and
55 // backends should at least have "read-after-create" consistency.
56 return $be->getFileContents( [ 'src' => $url ] );
57 }
58
59 return false;
60 }
61
69 public function batchFetchFromURLs( array $urls ) {
70 $pathsByBackend = [];
71 foreach ( $urls as $url ) {
72 $be = $this->fbGroup->backendFromPath( $url );
73 if ( $be instanceof FileBackend ) {
74 $pathsByBackend[$be->getName()][] = $url;
75 }
76 }
77 $blobs = [];
78 foreach ( $pathsByBackend as $backendName => $paths ) {
79 $be = $this->fbGroup->get( $backendName );
80 $blobs += $be->getFileContentsMulti( [ 'srcs' => $paths ] );
81 }
82
83 return $blobs;
84 }
85
87 public function store( $backend, $data ) {
88 $be = $this->fbGroup->get( $backend );
89 // Get three random base 36 characters to act as shard directories
90 $rand = \Wikimedia\base_convert( (string)mt_rand( 0, 46655 ), 10, 36, 3 );
91 // Make sure ID is roughly lexicographically increasing for performance
92 $gen = MediaWikiServices::getInstance()->getGlobalIdGenerator();
93 $id = str_pad( $gen->newTimestampedUID128( 32 ), 26, '0', STR_PAD_LEFT );
94 // Segregate items by DB domain ID for the sake of bookkeeping
95 $domain = $this->isDbDomainExplicit
96 ? $this->dbDomain
97 // @FIXME: this does not include the schema for b/c but it ideally should
98 : WikiMap::getWikiIdFromDbDomain( $this->dbDomain );
99 $url = $be->getContainerStoragePath( 'data' ) . '/' . rawurlencode( $domain );
100 // Use directory/container sharding
101 $url .= ( $be instanceof FSFileBackend )
102 ? "/{$rand[0]}/{$rand[1]}/{$rand[2]}/{$id}" // keep directories small
103 : "/{$rand[0]}/{$rand[1]}/{$id}"; // container sharding is only 2-levels
104
105 $be->prepare( [ 'dir' => dirname( $url ), 'noAccess' => 1, 'noListing' => 1 ] );
106 $status = $be->create( [ 'dst' => $url, 'content' => $data ] );
107
108 if ( $status->isOK() ) {
109 return $url;
110 }
111
112 throw new ExternalStoreException( __METHOD__ . ": operation failed: $status" );
113 }
114
116 public function isReadOnly( $backend ) {
117 if ( parent::isReadOnly( $backend ) ) {
118 return true;
119 }
120
121 $be = $this->fbGroup->get( $backend );
122
123 return $be->isReadOnly();
124 }
125}
126
128class_alias( ExternalStoreMwstore::class, 'ExternalStoreMwstore' );
array $params
Usage context options for this instance.
isReadOnly( $backend)
Check if a given location is read-only.bool Whether this location is read-only 1.31
batchFetchFromURLs(array $urls)
Fetch data from given external store URLs.
store( $backend, $data)
Insert a data item into a given location.string|bool The URL of the stored data item,...
fetchFromURL( $url)
Fetch data from a given external store URL.
Class to handle file backend registration.
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Tools for dealing with other locally-hosted wikis.
Definition WikiMap.php:19
Class for a file system (FS) based file backend.
Base class for all file backend classes (including multi-write backends).