70 public function mount( $prefix, $instance ) {
71 if ( !
preg_match( self::VALID_MOUNT_REGEX, $prefix ) ) {
72 throw new UnexpectedValueException(
"Invalid service mount point '$prefix'." );
74 throw new UnexpectedValueException(
"A service is already mounted on '$prefix'." );
77 if ( !
isset( $instance[
'class'] ) || !
isset( $instance[
'config'] ) ) {
78 throw new UnexpectedValueException(
"Missing 'class' or 'config' ('$prefix')." );
81 $this->instances[$prefix] = $instance;
90 if ( !
preg_match( self::VALID_MOUNT_REGEX, $prefix ) ) {
91 throw new UnexpectedValueException(
"Invalid service mount point '$prefix'." );
93 throw new UnexpectedValueException(
"No service is mounted on '$prefix'." );
95 unset( $this->instances[$prefix] );
164 foreach ( $reqs as $index => &
$req ) {
178 $armoredIndexMap = [];
182 $replaceReqsByService = [];
185 foreach ( $reqs as $origIndex =>
$req ) {
187 $index = $curUniqueId++;
189 $origPending[$index] = 1;
192 $executeReqs[$index] =
$req;
197 throw new UnexpectedValueException(
"Path '{$req['url']}' has no service." );
201 $replaceReqsByService[$prefix][$index] =
$req;
206 $idFunc =
function () use ( &$curUniqueId ) {
207 return $curUniqueId++;
212 if ( ++$rounds > 5 ) {
213 throw new Exception(
"Too many replacement rounds detected. Aborting." );
217 $checkReqIndexesByPrefix = [];
222 $newReplaceReqsByService = [];
223 foreach ( $replaceReqsByService as $prefix => $servReqs ) {
225 foreach ( $service->onRequests( $servReqs, $idFunc ) as $index =>
$req ) {
227 if (
isset( $servReqs[$index] ) ||
isset( $origPending[$index] ) ) {
231 $newReplaceReqsByService[$prefix][$index] =
$req;
235 unset( $executeReqs[$index] );
236 unset( $origPending[$index] );
237 $doneReqs[$index] =
$req;
240 $executeReqs[$index] =
$req;
242 $checkReqIndexesByPrefix[$prefix][$index] = 1;
246 foreach ( $this->
http->runMulti( $executeReqs ) as $index => $ranReq ) {
248 unset( $origPending[$index] );
256 $newReplaceReqsByService = [];
257 foreach ( $checkReqIndexesByPrefix as $prefix => $servReqIndexes ) {
261 foreach ( $service->onResponses( $servReqs, $idFunc ) as $index =>
$req ) {
263 if (
isset( $servReqs[$index] ) ||
isset( $origPending[$index] ) ) {
267 $newReplaceReqsByService[$prefix][$index] =
$req;
271 unset( $origPending[$index] );
272 $doneReqs[$index] =
$req;
275 $executeReqs[$index] =
$req;
281 }
while ( count( $origPending ) );
286 foreach ( $reqs as $origIndex =>
$req ) {
288 if ( !
isset( $doneReqs[$index] ) ) {
289 throw new UnexpectedValueException(
"Response for request '$index' is NULL." );
291 $responses[
$origIndex] = $doneReqs[$index][
'response'];
302 if ( !
isset( $this->instances[$prefix] ) ) {
303 throw new RuntimeException(
"No service registered at prefix '{$prefix}'." );
307 $config = $this->instances[$prefix][
'config'];
308 $class = $this->instances[$prefix][
'class'];
309 $service =
new $class( $config );
311 throw new UnexpectedValueException(
"Registered service has the wrong class." );
313 $this->instances[$prefix] =
$service;
316 return $this->instances[$prefix];