71 public function mount( $prefix, $instance ) {
72 if ( !preg_match( self::VALID_MOUNT_REGEX, $prefix ) ) {
73 throw new UnexpectedValueException(
"Invalid service mount point '$prefix'." );
74 } elseif ( isset( $this->instances[$prefix] ) ) {
75 throw new UnexpectedValueException(
"A service is already mounted on '$prefix'." );
78 if ( !isset( $instance[
'class'] ) || !isset( $instance[
'config'] ) ) {
79 throw new UnexpectedValueException(
"Missing 'class' or 'config' ('$prefix')." );
82 $this->instances[$prefix] = $instance;
91 if ( !preg_match( self::VALID_MOUNT_REGEX, $prefix ) ) {
92 throw new UnexpectedValueException(
"Invalid service mount point '$prefix'." );
93 } elseif ( !isset( $this->instances[$prefix] ) ) {
94 throw new UnexpectedValueException(
"No service is mounted on '$prefix'." );
96 unset( $this->instances[$prefix] );
168 foreach ( $reqs
as $index => &
$req ) {
169 if ( isset(
$req[0] ) ) {
173 if ( isset(
$req[1] ) ) {
182 $armoredIndexMap = [];
186 $replaceReqsByService = [];
189 foreach ( $reqs
as $origIndex =>
$req ) {
191 $index = $curUniqueId++;
192 $armoredIndexMap[$origIndex] = $index;
193 $origPending[$index] = 1;
194 if ( preg_match(
'#^(http|ftp)s?://#',
$req[
'url'] ) ) {
196 $executeReqs[$index] =
$req;
201 throw new UnexpectedValueException(
"Path '{$req['url']}' has no service." );
204 $req[
'url'] = substr(
$req[
'url'], strlen( $prefix ) );
205 $replaceReqsByService[$prefix][$index] =
$req;
210 $idFunc =
function()
use ( &$curUniqueId ) {
211 return $curUniqueId++;
216 if ( ++$rounds > 5 ) {
217 throw new Exception(
"Too many replacement rounds detected. Aborting." );
221 $checkReqIndexesByPrefix = [];
226 $newReplaceReqsByService = [];
227 foreach ( $replaceReqsByService
as $prefix => $servReqs ) {
229 foreach ( $service->onRequests( $servReqs, $idFunc )
as $index =>
$req ) {
231 if ( isset( $servReqs[$index] ) || isset( $origPending[$index] ) ) {
235 $newReplaceReqsByService[$prefix][$index] =
$req;
237 if ( isset(
$req[
'response'] ) ) {
239 unset( $executeReqs[$index] );
240 unset( $origPending[$index] );
241 $doneReqs[$index] =
$req;
244 $executeReqs[$index] =
$req;
246 $checkReqIndexesByPrefix[$prefix][$index] = 1;
250 foreach ( $this->
http->runMulti( $executeReqs )
as $index => $ranReq ) {
251 $doneReqs[$index] = $ranReq;
252 unset( $origPending[$index] );
260 $newReplaceReqsByService = [];
261 foreach ( $checkReqIndexesByPrefix
as $prefix => $servReqIndexes ) {
264 $servReqs = array_intersect_key( $doneReqs, $servReqIndexes );
265 foreach ( $service->onResponses( $servReqs, $idFunc )
as $index =>
$req ) {
267 if ( isset( $servReqs[$index] ) || isset( $origPending[$index] ) ) {
271 $newReplaceReqsByService[$prefix][$index] =
$req;
273 if ( isset(
$req[
'response'] ) ) {
275 unset( $origPending[$index] );
276 $doneReqs[$index] =
$req;
279 $executeReqs[$index] =
$req;
284 $replaceReqsByService = $newReplaceReqsByService;
285 }
while ( count( $origPending ) );
290 foreach ( $reqs
as $origIndex =>
$req ) {
291 $index = $armoredIndexMap[$origIndex];
292 if ( !isset( $doneReqs[$index] ) ) {
293 throw new UnexpectedValueException(
"Response for request '$index' is NULL." );
295 $responses[$origIndex] = $doneReqs[$index][
'response'];
306 if ( !isset( $this->instances[$prefix] ) ) {
307 throw new RuntimeException(
"No service registered at prefix '{$prefix}'." );
311 $config = $this->instances[$prefix][
'config'];
312 $class = $this->instances[$prefix][
'class'];
313 $service =
new $class( $config );
315 throw new UnexpectedValueException(
"Registered service has the wrong class." );
317 $this->instances[$prefix] = $service;
320 return $this->instances[$prefix];