File manager - Edit - /var/www/payraty/helpdesk/public/storage/branding_media/images/src.zip
Back
PK ! �(�� � Token.phpnu ȯ�� <?php declare(strict_types=1); namespace Doctrine\Common\Lexer; use UnitEnum; use function in_array; /** * @template T of UnitEnum|string|int * @template V of string|int */ final class Token { /** * The string value of the token in the input string * * @readonly * @var V */ public string|int $value; /** * The type of the token (identifier, numeric, string, input parameter, none) * * @readonly * @var T|null */ public $type; /** * The position of the token in the input string * * @readonly */ public int $position; /** * @param V $value * @param T|null $type */ public function __construct(string|int $value, $type, int $position) { $this->value = $value; $this->type = $type; $this->position = $position; } /** @param T ...$types */ public function isA(...$types): bool { return in_array($this->type, $types, true); } } PK ! ��� AbstractLexer.phpnu ȯ�� <?php declare(strict_types=1); namespace Doctrine\Common\Lexer; use ReflectionClass; use UnitEnum; use function implode; use function preg_split; use function sprintf; use function substr; use const PREG_SPLIT_DELIM_CAPTURE; use const PREG_SPLIT_NO_EMPTY; use const PREG_SPLIT_OFFSET_CAPTURE; /** * Base class for writing simple lexers, i.e. for creating small DSLs. * * @template T of UnitEnum|string|int * @template V of string|int */ abstract class AbstractLexer { /** * Lexer original input string. */ private string $input; /** * Array of scanned tokens. * * @var list<Token<T, V>> */ private array $tokens = []; /** * Current lexer position in input string. */ private int $position = 0; /** * Current peek of current lexer position. */ private int $peek = 0; /** * The next token in the input. * * @var Token<T, V>|null */ public Token|null $lookahead; /** * The last matched/seen token. * * @var Token<T, V>|null */ public Token|null $token; /** * Composed regex for input parsing. * * @var non-empty-string|null */ private string|null $regex = null; /** * Sets the input data to be tokenized. * * The Lexer is immediately reset and the new input tokenized. * Any unprocessed tokens from any previous input are lost. * * @param string $input The input to be tokenized. * * @return void */ public function setInput(string $input) { $this->input = $input; $this->tokens = []; $this->reset(); $this->scan($input); } /** * Resets the lexer. * * @return void */ public function reset() { $this->lookahead = null; $this->token = null; $this->peek = 0; $this->position = 0; } /** * Resets the peek pointer to 0. * * @return void */ public function resetPeek() { $this->peek = 0; } /** * Resets the lexer position on the input to the given position. * * @param int $position Position to place the lexical scanner. * * @return void */ public function resetPosition(int $position = 0) { $this->position = $position; } /** * Retrieve the original lexer's input until a given position. * * @return string */ public function getInputUntilPosition(int $position) { return substr($this->input, 0, $position); } /** * Checks whether a given token matches the current lookahead. * * @param T $type * * @return bool * * @psalm-assert-if-true !=null $this->lookahead */ public function isNextToken(int|string|UnitEnum $type) { return $this->lookahead !== null && $this->lookahead->isA($type); } /** * Checks whether any of the given tokens matches the current lookahead. * * @param list<T> $types * * @return bool * * @psalm-assert-if-true !=null $this->lookahead */ public function isNextTokenAny(array $types) { return $this->lookahead !== null && $this->lookahead->isA(...$types); } /** * Moves to the next token in the input string. * * @return bool * * @psalm-assert-if-true !null $this->lookahead */ public function moveNext() { $this->peek = 0; $this->token = $this->lookahead; $this->lookahead = isset($this->tokens[$this->position]) ? $this->tokens[$this->position++] : null; return $this->lookahead !== null; } /** * Tells the lexer to skip input tokens until it sees a token with the given value. * * @param T $type The token type to skip until. * * @return void */ public function skipUntil(int|string|UnitEnum $type) { while ($this->lookahead !== null && ! $this->lookahead->isA($type)) { $this->moveNext(); } } /** * Checks if given value is identical to the given token. * * @return bool */ public function isA(string $value, int|string|UnitEnum $token) { return $this->getType($value) === $token; } /** * Moves the lookahead token forward. * * @return Token<T, V>|null The next token or NULL if there are no more tokens ahead. */ public function peek() { if (isset($this->tokens[$this->position + $this->peek])) { return $this->tokens[$this->position + $this->peek++]; } return null; } /** * Peeks at the next token, returns it and immediately resets the peek. * * @return Token<T, V>|null The next token or NULL if there are no more tokens ahead. */ public function glimpse() { $peek = $this->peek(); $this->peek = 0; return $peek; } /** * Scans the input string for tokens. * * @param string $input A query string. * * @return void */ protected function scan(string $input) { if (! isset($this->regex)) { $this->regex = sprintf( '/(%s)|%s/%s', implode(')|(', $this->getCatchablePatterns()), implode('|', $this->getNonCatchablePatterns()), $this->getModifiers(), ); } $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE; $matches = preg_split($this->regex, $input, -1, $flags); if ($matches === false) { // Work around https://bugs.php.net/78122 $matches = [[$input, 0]]; } foreach ($matches as $match) { // Must remain before 'value' assignment since it can change content $firstMatch = $match[0]; $type = $this->getType($firstMatch); $this->tokens[] = new Token( $firstMatch, $type, $match[1], ); } } /** * Gets the literal for a given token. * * @param T $token * * @return int|string */ public function getLiteral(int|string|UnitEnum $token) { if ($token instanceof UnitEnum) { return $token::class . '::' . $token->name; } $className = static::class; $reflClass = new ReflectionClass($className); $constants = $reflClass->getConstants(); foreach ($constants as $name => $value) { if ($value === $token) { return $className . '::' . $name; } } return $token; } /** * Regex modifiers * * @return string */ protected function getModifiers() { return 'iu'; } /** * Lexical catchable patterns. * * @return string[] */ abstract protected function getCatchablePatterns(); /** * Lexical non-catchable patterns. * * @return string[] */ abstract protected function getNonCatchablePatterns(); /** * Retrieve token type. Also processes the token value if necessary. * * @return T|null * * @param-out V $value */ abstract protected function getType(string &$value); } PK ! �7E lib/RpcServer.phpnu ȯ�� <?php /* * * Copyright 2020 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * This is an experimental and incomplete implementation of gRPC server * for PHP. APIs are _definitely_ going to be changed. * * DO NOT USE in production. */ /** * Class RpcServer * @package Grpc */ class RpcServer extends Server { // [ <String method_full_path> => MethodDescriptor ] private $paths_map = []; private function waitForNextEvent() { return $this->requestCall(); } /** * Add a service to this server * * @param Object $service The service to be added */ public function handle($service) { $methodDescriptors = $service->getMethodDescriptors(); $exist_methods = array_intersect_key($this->paths_map, $methodDescriptors); if (!empty($exist_methods)) { fwrite(STDERR, "WARNING: " . 'override already registered methods: ' . implode(', ', array_keys($exist_methods)) . PHP_EOL); } $this->paths_map = array_merge($this->paths_map, $methodDescriptors); return $this->paths_map; } public function run() { $this->start(); while (true) try { // This blocks until the server receives a request $event = $this->waitForNextEvent(); $full_path = $event->method; $context = new ServerContext($event); $server_writer = new ServerCallWriter($event->call, $context); if (!array_key_exists($full_path, $this->paths_map)) { $context->setStatus(Status::unimplemented()); $server_writer->finish(); continue; }; $method_desc = $this->paths_map[$full_path]; $server_reader = new ServerCallReader( $event->call, $method_desc->request_type ); try { $this->processCall( $method_desc, $server_reader, $server_writer, $context ); } catch (\Exception $e) { $context->setStatus(Status::status( STATUS_INTERNAL, $e->getMessage() )); $server_writer->finish(); } } catch (\Exception $e) { fwrite(STDERR, "ERROR: " . $e->getMessage() . PHP_EOL); exit(1); } } private function processCall( MethodDescriptor $method_desc, ServerCallReader $server_reader, ServerCallWriter $server_writer, ServerContext $context ) { // Dispatch to actual server logic switch ($method_desc->call_type) { case MethodDescriptor::UNARY_CALL: $request = $server_reader->read(); $response = call_user_func( array($method_desc->service, $method_desc->method_name), $request ?? new $method_desc->request_type, $context ); $server_writer->finish($response); break; case MethodDescriptor::SERVER_STREAMING_CALL: $request = $server_reader->read(); call_user_func( array($method_desc->service, $method_desc->method_name), $request ?? new $method_desc->request_type, $server_writer, $context ); break; case MethodDescriptor::CLIENT_STREAMING_CALL: $response = call_user_func( array($method_desc->service, $method_desc->method_name), $server_reader, $context ); $server_writer->finish($response); break; case MethodDescriptor::BIDI_STREAMING_CALL: call_user_func( array($method_desc->service, $method_desc->method_name), $server_reader, $server_writer, $context ); break; default: throw new \Exception(); } } } PK ! �Bs? ? lib/ClientStreamingCall.phpnu ȯ�� <?php /* * * Copyright 2015 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * Represents an active call that sends a stream of messages and then gets * a single response. */ class ClientStreamingCall extends AbstractCall { /** * Start the call. * * @param array $metadata Metadata to send with the call, if applicable * (optional) */ public function start(array $metadata = []) { $this->call->startBatch([ OP_SEND_INITIAL_METADATA => $metadata, ]); } /** * Write a single message to the server. This cannot be called after * wait is called. * * @param ByteBuffer $data The data to write * @param array $options An array of options, possible keys: * 'flags' => a number (optional) */ public function write($data, array $options = []) { $message_array = ['message' => $this->_serializeMessage($data)]; if (array_key_exists('flags', $options)) { $message_array['flags'] = $options['flags']; } $this->call->startBatch([ OP_SEND_MESSAGE => $message_array, ]); } /** * Wait for the server to respond with data and a status. * * @return array [response data, status] */ public function wait() { $event = $this->call->startBatch([ OP_SEND_CLOSE_FROM_CLIENT => true, OP_RECV_INITIAL_METADATA => true, OP_RECV_MESSAGE => true, OP_RECV_STATUS_ON_CLIENT => true, ]); $this->metadata = $event->metadata; $status = $event->status; $this->trailing_metadata = $status->metadata; return [$this->_deserializeResponse($event->message), $status]; } } PK ! ���� � lib/ServerCallWriter.phpnu ȯ�� <?php /* * * Copyright 2020 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * This is an experimental and incomplete implementation of gRPC server * for PHP. APIs are _definitely_ going to be changed. * * DO NOT USE in production. */ class ServerCallWriter { public function __construct($call, $serverContext) { $this->call_ = $call; $this->serverContext_ = $serverContext; } public function start( $data = null, array $options = [] ) { $batch = []; $this->addSendInitialMetadataOpIfNotSent( $batch, $this->serverContext_->initialMetadata() ); $this->addSendMessageOpIfHasData($batch, $data, $options); $this->call_->startBatch($batch); } public function write( $data, array $options = [] ) { $batch = []; $this->addSendInitialMetadataOpIfNotSent( $batch, $this->serverContext_->initialMetadata() ); $this->addSendMessageOpIfHasData($batch, $data, $options); $this->call_->startBatch($batch); } public function finish( $data = null, array $options = [] ) { $batch = [ OP_SEND_STATUS_FROM_SERVER => $this->serverContext_->status() ?? Status::ok(), OP_RECV_CLOSE_ON_SERVER => true, ]; $this->addSendInitialMetadataOpIfNotSent( $batch, $this->serverContext_->initialMetadata() ); $this->addSendMessageOpIfHasData($batch, $data, $options); $this->call_->startBatch($batch); } //////////////////////////// private function addSendInitialMetadataOpIfNotSent( array &$batch, array $initialMetadata = null ) { if (!$this->initialMetadataSent_) { $batch[OP_SEND_INITIAL_METADATA] = $initialMetadata ?? []; $this->initialMetadataSent_ = true; } } private function addSendMessageOpIfHasData( array &$batch, $data = null, array $options = [] ) { if ($data) { $message_array = ['message' => $data->serializeToString()]; if (array_key_exists('flags', $options)) { $message_array['flags'] = $options['flags']; } $batch[OP_SEND_MESSAGE] = $message_array; } } private $call_; private $initialMetadataSent_ = false; private $serverContext_; } PK ! B�i i lib/Interceptor.phpnu ȯ�� <?php /* * * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * Represents an interceptor that intercept RPC invocations before call starts. * There is one proposal related to the argument $deserialize under the review. * The proposal link is https://github.com/grpc/proposal/pull/86. */ class Interceptor { public function interceptUnaryUnary( $method, $argument, $deserialize, $continuation, array $metadata = [], array $options = [] ) { return $continuation($method, $argument, $deserialize, $metadata, $options); } public function interceptStreamUnary( $method, $deserialize, $continuation, array $metadata = [], array $options = [] ) { return $continuation($method, $deserialize, $metadata, $options); } public function interceptUnaryStream( $method, $argument, $deserialize, $continuation, array $metadata = [], array $options = [] ) { return $continuation($method, $argument, $deserialize, $metadata, $options); } public function interceptStreamStream( $method, $deserialize, $continuation, array $metadata = [], array $options = [] ) { return $continuation($method, $deserialize, $metadata, $options); } /** * Intercept the methods with Channel * * @param Channel|InterceptorChannel $channel An already created Channel or InterceptorChannel object (optional) * @param Interceptor|Interceptor[] $interceptors interceptors to be added * * @return InterceptorChannel */ public static function intercept($channel, $interceptors) { if (is_array($interceptors)) { for ($i = count($interceptors) - 1; $i >= 0; $i--) { $channel = new Internal\InterceptorChannel($channel, $interceptors[$i]); } } else { $channel = new Internal\InterceptorChannel($channel, $interceptors); } return $channel; } } PK ! g�hW lib/UnaryCall.phpnu ȯ�� <?php /* * * Copyright 2015 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * Represents an active call that sends a single message and then gets a * single response. */ class UnaryCall extends AbstractCall { /** * Start the call. * * @param mixed $data The data to send * @param array $metadata Metadata to send with the call, if applicable * (optional) * @param array $options An array of options, possible keys: * 'flags' => a number (optional) */ public function start($data, array $metadata = [], array $options = []) { $message_array = ['message' => $this->_serializeMessage($data)]; if (isset($options['flags'])) { $message_array['flags'] = $options['flags']; } $this->call->startBatch([ OP_SEND_INITIAL_METADATA => $metadata, OP_SEND_MESSAGE => $message_array, OP_SEND_CLOSE_FROM_CLIENT => true, ]); } /** * Wait for the server to respond with data and a status. * * @return array [response data, status] */ public function wait() { $batch = [ OP_RECV_MESSAGE => true, OP_RECV_STATUS_ON_CLIENT => true, ]; if ($this->metadata === null) { $batch[OP_RECV_INITIAL_METADATA] = true; } $event = $this->call->startBatch($batch); if ($this->metadata === null) { $this->metadata = $event->metadata; } $status = $event->status; $this->trailing_metadata = $status->metadata; return [$this->_deserializeResponse($event->message), $status]; } /** * @return mixed The metadata sent by the server */ public function getMetadata() { if ($this->metadata === null) { $event = $this->call->startBatch([OP_RECV_INITIAL_METADATA => true]); $this->metadata = $event->metadata; } return $this->metadata; } } PK ! �� lib/ServerStreamingCall.phpnu ȯ�� <?php /* * * Copyright 2015 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * Represents an active call that sends a single message and then gets a * stream of responses. */ class ServerStreamingCall extends AbstractCall { /** * Start the call. * * @param mixed $data The data to send * @param array $metadata Metadata to send with the call, if applicable * (optional) * @param array $options An array of options, possible keys: * 'flags' => a number (optional) */ public function start($data, array $metadata = [], array $options = []) { $message_array = ['message' => $this->_serializeMessage($data)]; if (array_key_exists('flags', $options)) { $message_array['flags'] = $options['flags']; } $this->call->startBatch([ OP_SEND_INITIAL_METADATA => $metadata, OP_SEND_MESSAGE => $message_array, OP_SEND_CLOSE_FROM_CLIENT => true, ]); } /** * @return mixed An iterator of response values */ public function responses() { $batch = [OP_RECV_MESSAGE => true]; if ($this->metadata === null) { $batch[OP_RECV_INITIAL_METADATA] = true; } $read_event = $this->call->startBatch($batch); if ($this->metadata === null) { $this->metadata = $read_event->metadata; } $response = $read_event->message; while ($response !== null) { yield $this->_deserializeResponse($response); $response = $this->call->startBatch([ OP_RECV_MESSAGE => true, ])->message; } } /** * Wait for the server to send the status, and return it. * * @return \stdClass The status object, with integer $code, string * $details, and array $metadata members */ public function getStatus() { $status_event = $this->call->startBatch([ OP_RECV_STATUS_ON_CLIENT => true, ]); $this->trailing_metadata = $status_event->status->metadata; return $status_event->status; } /** * @return mixed The metadata sent by the server */ public function getMetadata() { if ($this->metadata === null) { $event = $this->call->startBatch([OP_RECV_INITIAL_METADATA => true]); $this->metadata = $event->metadata; } return $this->metadata; } } PK ! p?-� � lib/CallInvoker.phpnu ȯ�� <?php /* * * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * CallInvoker is used to pass the self defined channel into the stub, * while intercept each RPC with the channel accessible. */ interface CallInvoker { public function createChannelFactory($hostname, $opts); public function UnaryCall($channel, $method, $deserialize, $options); public function ClientStreamingCall($channel, $method, $deserialize, $options); public function ServerStreamingCall($channel, $method, $deserialize, $options); public function BidiStreamingCall($channel, $method, $deserialize, $options); } PK ! ��R R # lib/Internal/InterceptorChannel.phpnu ȯ�� <?php /* * * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc\Internal; /** * This is a PRIVATE API and can change without notice. */ class InterceptorChannel extends \Grpc\Channel { private $next = null; private $interceptor; /** * @param Channel|InterceptorChannel $channel An already created Channel * or InterceptorChannel object (optional) * @param Interceptor $interceptor */ public function __construct($channel, $interceptor) { if (!is_a($channel, 'Grpc\Channel') && !is_a($channel, 'Grpc\Internal\InterceptorChannel')) { throw new \Exception('The channel argument is not a Channel object '. 'or an InterceptorChannel object created by '. 'Interceptor::intercept($channel, Interceptor|Interceptor[] $interceptors)'); } $this->interceptor = $interceptor; $this->next = $channel; } public function getNext() { return $this->next; } public function getInterceptor() { return $this->interceptor; } public function getTarget() { return $this->getNext()->getTarget(); } public function watchConnectivityState($new_state, $deadline) { return $this->getNext()->watchConnectivityState($new_state, $deadline); } public function getConnectivityState($try_to_connect = false) { return $this->getNext()->getConnectivityState($try_to_connect); } public function close() { return $this->getNext()->close(); } } PK ! ��i �R �R lib/BaseStub.phpnu ȯ�� <?php /* * * Copyright 2015 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * Base class for generated client stubs. Stub methods are expected to call * _simpleRequest or _streamRequest and return the result. */ class BaseStub { private $hostname; private $hostname_override; private $channel; private $call_invoker; // a callback function private $update_metadata; /** * @param string $hostname * @param array $opts * - 'update_metadata': (optional) a callback function which takes in a * metadata array, and returns an updated metadata array * - 'grpc.primary_user_agent': (optional) a user-agent string * @param Channel|InterceptorChannel $channel An already created Channel or InterceptorChannel object (optional) */ public function __construct($hostname, $opts, $channel = null) { if (!method_exists('Grpc\ChannelCredentials', 'isDefaultRootsPemSet') || !ChannelCredentials::isDefaultRootsPemSet()) { $ssl_roots = file_get_contents( dirname(__FILE__).'/../../etc/roots.pem' ); ChannelCredentials::setDefaultRootsPem($ssl_roots); } $this->hostname = $hostname; $this->update_metadata = null; if (isset($opts['update_metadata'])) { if (is_callable($opts['update_metadata'])) { $this->update_metadata = $opts['update_metadata']; } unset($opts['update_metadata']); } if (!empty($opts['grpc.ssl_target_name_override'])) { $this->hostname_override = $opts['grpc.ssl_target_name_override']; } if (isset($opts['grpc_call_invoker'])) { $this->call_invoker = $opts['grpc_call_invoker']; unset($opts['grpc_call_invoker']); $channel_opts = $this->updateOpts($opts); // If the grpc_call_invoker is defined, use the channel created by the call invoker. $this->channel = $this->call_invoker->createChannelFactory($hostname, $channel_opts); return; } $this->call_invoker = new DefaultCallInvoker(); if ($channel) { if (!is_a($channel, 'Grpc\Channel') && !is_a($channel, 'Grpc\Internal\InterceptorChannel')) { throw new \Exception('The channel argument is not a Channel object '. 'or an InterceptorChannel object created by '. 'Interceptor::intercept($channel, Interceptor|Interceptor[] $interceptors)'); } $this->channel = $channel; return; } $this->channel = static::getDefaultChannel($hostname, $opts); } private static function updateOpts($opts) { if (!empty($opts['grpc.primary_user_agent'])) { $opts['grpc.primary_user_agent'] .= ' '; } else { $opts['grpc.primary_user_agent'] = ''; } if (defined('\Grpc\VERSION')) { $version_str = \Grpc\VERSION; } else { if (!file_exists($composerFile = __DIR__.'/../../composer.json')) { // for grpc/grpc-php subpackage $composerFile = __DIR__.'/../composer.json'; } $package_config = json_decode(file_get_contents($composerFile), true); $version_str = $package_config['version']; } $opts['grpc.primary_user_agent'] .= 'grpc-php/'.$version_str; if (!array_key_exists('credentials', $opts)) { throw new \Exception("The opts['credentials'] key is now ". 'required. Please see one of the '. 'ChannelCredentials::create methods'); } return $opts; } /** * Creates and returns the default Channel * * @param array $opts Channel constructor options * * @return Channel The channel */ public static function getDefaultChannel($hostname, array $opts) { $channel_opts = self::updateOpts($opts); return new Channel($hostname, $channel_opts); } /** * @return string The URI of the endpoint */ public function getTarget() { return $this->channel->getTarget(); } /** * @param bool $try_to_connect (optional) * * @return int The grpc connectivity state */ public function getConnectivityState($try_to_connect = false) { return $this->channel->getConnectivityState($try_to_connect); } /** * @param int $timeout in microseconds * * @return bool true if channel is ready * @throws Exception if channel is in FATAL_ERROR state */ public function waitForReady($timeout) { $new_state = $this->getConnectivityState(true); if ($this->_checkConnectivityState($new_state)) { return true; } $now = Timeval::now(); $delta = new Timeval($timeout); $deadline = $now->add($delta); while ($this->channel->watchConnectivityState($new_state, $deadline)) { // state has changed before deadline $new_state = $this->getConnectivityState(); if ($this->_checkConnectivityState($new_state)) { return true; } } // deadline has passed $new_state = $this->getConnectivityState(); return $this->_checkConnectivityState($new_state); } /** * Close the communication channel associated with this stub. */ public function close() { $this->channel->close(); } /** * @param $new_state Connect state * * @return bool true if state is CHANNEL_READY * @throws Exception if state is CHANNEL_FATAL_FAILURE */ private function _checkConnectivityState($new_state) { if ($new_state == \Grpc\CHANNEL_READY) { return true; } if ($new_state == \Grpc\CHANNEL_FATAL_FAILURE) { throw new \Exception('Failed to connect to server'); } return false; } /** * constructs the auth uri for the jwt. * * @param string $method The method string * * @return string The URL string */ private function _get_jwt_aud_uri($method) { // TODO(jtattermusch): This is not the correct implementation // of extracting JWT "aud" claim. We should rely on // grpc_metadata_credentials_plugin which // also provides the correct value of "aud" claim // in the grpc_auth_metadata_context.service_url field. // Trying to do the construction of "aud" field ourselves // is bad. $last_slash_idx = strrpos($method, '/'); if ($last_slash_idx === false) { throw new \InvalidArgumentException( 'service name must have a slash' ); } $service_name = substr($method, 0, $last_slash_idx); if ($this->hostname_override) { $hostname = $this->hostname_override; } else { $hostname = $this->hostname; } // Remove the port if it is 443 // See https://github.com/grpc/grpc/blob/07c9f7a36b2a0d34fcffebc85649cf3b8c339b5d/src/core/lib/security/transport/client_auth_filter.cc#L205 if ((strlen($hostname) > 4) && (substr($hostname, -4) === ":443")) { $hostname = substr($hostname, 0, -4); } return 'https://'.$hostname.$service_name; } /** * validate and normalize the metadata array. * * @param array $metadata The metadata map * * @return array $metadata Validated and key-normalized metadata map * @throws InvalidArgumentException if key contains invalid characters */ private function _validate_and_normalize_metadata($metadata) { $metadata_copy = []; foreach ($metadata as $key => $value) { if (!preg_match('/^[.A-Za-z\d_-]+$/', $key)) { throw new \InvalidArgumentException( 'Metadata keys must be nonempty strings containing only '. 'alphanumeric characters, hyphens, underscores and dots' ); } $metadata_copy[strtolower($key)] = $value; } return $metadata_copy; } /** * Create a function which can be used to create UnaryCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _GrpcUnaryUnary($channel) { return function ($method, $argument, $deserialize, array $metadata = [], array $options = []) use ($channel) { $call = $this->call_invoker->UnaryCall( $channel, $method, $deserialize, $options ); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { $metadata = call_user_func( $this->update_metadata, $metadata, $jwt_aud_uri ); } $metadata = $this->_validate_and_normalize_metadata( $metadata ); $call->start($argument, $metadata, $options); return $call; }; } /** * Create a function which can be used to create ServerStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _GrpcStreamUnary($channel) { return function ($method, $deserialize, array $metadata = [], array $options = []) use ($channel) { $call = $this->call_invoker->ClientStreamingCall( $channel, $method, $deserialize, $options ); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { $metadata = call_user_func( $this->update_metadata, $metadata, $jwt_aud_uri ); } $metadata = $this->_validate_and_normalize_metadata( $metadata ); $call->start($metadata); return $call; }; } /** * Create a function which can be used to create ClientStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _GrpcUnaryStream($channel) { return function ($method, $argument, $deserialize, array $metadata = [], array $options = []) use ($channel) { $call = $this->call_invoker->ServerStreamingCall( $channel, $method, $deserialize, $options ); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { $metadata = call_user_func( $this->update_metadata, $metadata, $jwt_aud_uri ); } $metadata = $this->_validate_and_normalize_metadata( $metadata ); $call->start($argument, $metadata, $options); return $call; }; } /** * Create a function which can be used to create BidiStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _GrpcStreamStream($channel) { return function ($method, $deserialize, array $metadata = [], array $options = []) use ($channel) { $call = $this->call_invoker->BidiStreamingCall( $channel, $method, $deserialize, $options ); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { $metadata = call_user_func( $this->update_metadata, $metadata, $jwt_aud_uri ); } $metadata = $this->_validate_and_normalize_metadata( $metadata ); $call->start($metadata); return $call; }; } /** * Create a function which can be used to create UnaryCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _UnaryUnaryCallFactory($channel) { if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { return function ($method, $argument, $deserialize, array $metadata = [], array $options = []) use ($channel) { return $channel->getInterceptor()->interceptUnaryUnary( $method, $argument, $deserialize, $this->_UnaryUnaryCallFactory($channel->getNext()), $metadata, $options ); }; } return $this->_GrpcUnaryUnary($channel); } /** * Create a function which can be used to create ServerStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _UnaryStreamCallFactory($channel) { if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { return function ($method, $argument, $deserialize, array $metadata = [], array $options = []) use ($channel) { return $channel->getInterceptor()->interceptUnaryStream( $method, $argument, $deserialize, $this->_UnaryStreamCallFactory($channel->getNext()), $metadata, $options ); }; } return $this->_GrpcUnaryStream($channel); } /** * Create a function which can be used to create ClientStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _StreamUnaryCallFactory($channel) { if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { return function ($method, $deserialize, array $metadata = [], array $options = []) use ($channel) { return $channel->getInterceptor()->interceptStreamUnary( $method, $deserialize, $this->_StreamUnaryCallFactory($channel->getNext()), $metadata, $options ); }; } return $this->_GrpcStreamUnary($channel); } /** * Create a function which can be used to create BidiStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _StreamStreamCallFactory($channel) { if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { return function ($method, $deserialize, array $metadata = [], array $options = []) use ($channel) { return $channel->getInterceptor()->interceptStreamStream( $method, $deserialize, $this->_StreamStreamCallFactory($channel->getNext()), $metadata, $options ); }; } return $this->_GrpcStreamStream($channel); } /* This class is intended to be subclassed by generated code, so * all functions begin with "_" to avoid name collisions. */ /** * Call a remote method that takes a single argument and has a * single output. * * @param string $method The name of the method to call * @param mixed $argument The argument to the method * @param callable $deserialize A function that deserializes the response * @param array $metadata A metadata map to send to the server * (optional) * @param array $options An array of options (optional) * * @return UnaryCall The active call object */ protected function _simpleRequest( $method, $argument, $deserialize, array $metadata = [], array $options = [] ) { $call_factory = $this->_UnaryUnaryCallFactory($this->channel); $call = $call_factory($method, $argument, $deserialize, $metadata, $options); return $call; } /** * Call a remote method that takes a stream of arguments and has a single * output. * * @param string $method The name of the method to call * @param callable $deserialize A function that deserializes the response * @param array $metadata A metadata map to send to the server * (optional) * @param array $options An array of options (optional) * * @return ClientStreamingCall The active call object */ protected function _clientStreamRequest( $method, $deserialize, array $metadata = [], array $options = [] ) { $call_factory = $this->_StreamUnaryCallFactory($this->channel); $call = $call_factory($method, $deserialize, $metadata, $options); return $call; } /** * Call a remote method that takes a single argument and returns a stream * of responses. * * @param string $method The name of the method to call * @param mixed $argument The argument to the method * @param callable $deserialize A function that deserializes the responses * @param array $metadata A metadata map to send to the server * (optional) * @param array $options An array of options (optional) * * @return ServerStreamingCall The active call object */ protected function _serverStreamRequest( $method, $argument, $deserialize, array $metadata = [], array $options = [] ) { $call_factory = $this->_UnaryStreamCallFactory($this->channel); $call = $call_factory($method, $argument, $deserialize, $metadata, $options); return $call; } /** * Call a remote method with messages streaming in both directions. * * @param string $method The name of the method to call * @param callable $deserialize A function that deserializes the responses * @param array $metadata A metadata map to send to the server * (optional) * @param array $options An array of options (optional) * * @return BidiStreamingCall The active call object */ protected function _bidiRequest( $method, $deserialize, array $metadata = [], array $options = [] ) { $call_factory = $this->_StreamStreamCallFactory($this->channel); $call = $call_factory($method, $deserialize, $metadata, $options); return $call; } } PK ! �ꒁ� � lib/Status.phpnu ȯ�� <?php /* * * Copyright 2020 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * This is an experimental and incomplete implementation of gRPC server * for PHP. APIs are _definitely_ going to be changed. * * DO NOT USE in production. */ /** * Class Status * @package Grpc */ class Status { public static function status(int $code, string $details, array $metadata = null): array { $status = [ 'code' => $code, 'details' => $details, ]; if ($metadata) { $status['metadata'] = $metadata; } return $status; } public static function ok(array $metadata = null): array { return Status::status(STATUS_OK, 'OK', $metadata); } public static function unimplemented(): array { return Status::status(STATUS_UNIMPLEMENTED, 'UNIMPLEMENTED'); } } PK ! �n � � lib/ServerContext.phpnu ȯ�� <?php /* * * Copyright 2020 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * This is an experimental and incomplete implementation of gRPC server * for PHP. APIs are _definitely_ going to be changed. * * DO NOT USE in production. */ class ServerContext { public function __construct($event) { $this->event = $event; } public function clientMetadata() { return $this->event->metadata; } public function deadline() { return $this->event->absolute_deadline; } public function host() { return $this->event->host; } public function method() { return $this->event->method; } public function setInitialMetadata($initialMetadata) { $this->initialMetadata_ = $initialMetadata; } public function initialMetadata() { return $this->initialMetadata_; } public function setStatus($status) { $this->status_ = $status; } public function status() { return $this->status_; } private $event; private $initialMetadata_; private $status_; } PK ! Ӵ�Tv v lib/MethodDescriptor.phpnu ȯ�� <?php /* * * Copyright 2020 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * This is an experimental and incomplete implementation of gRPC server * for PHP. APIs are _definitely_ going to be changed. * * DO NOT USE in production. */ class MethodDescriptor { public function __construct( object $service, string $method_name, string $request_type, int $call_type ) { $this->service = $service; $this->method_name = $method_name; $this->request_type = $request_type; $this->call_type = $call_type; } public const UNARY_CALL = 0; public const SERVER_STREAMING_CALL = 1; public const CLIENT_STREAMING_CALL = 2; public const BIDI_STREAMING_CALL = 3; public $service; public $method_name; public $request_type; public $call_type; } PK ! ��� � lib/BidiStreamingCall.phpnu ȯ�� <?php /* * * Copyright 2015 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * Represents an active call that allows for sending and receiving messages * in streams in any order. */ class BidiStreamingCall extends AbstractCall { /** * Start the call. * * @param array $metadata Metadata to send with the call, if applicable * (optional) */ public function start(array $metadata = []) { $this->call->startBatch([ OP_SEND_INITIAL_METADATA => $metadata, ]); } /** * Reads the next value from the server. * * @return mixed The next value from the server, or null if there is none */ public function read() { $batch = [OP_RECV_MESSAGE => true]; if ($this->metadata === null) { $batch[OP_RECV_INITIAL_METADATA] = true; } $read_event = $this->call->startBatch($batch); if ($this->metadata === null) { $this->metadata = $read_event->metadata; } return $this->_deserializeResponse($read_event->message); } /** * Write a single message to the server. This cannot be called after * writesDone is called. * * @param ByteBuffer $data The data to write * @param array $options An array of options, possible keys: * 'flags' => a number (optional) */ public function write($data, array $options = []) { $message_array = ['message' => $this->_serializeMessage($data)]; if (array_key_exists('flags', $options)) { $message_array['flags'] = $options['flags']; } $this->call->startBatch([ OP_SEND_MESSAGE => $message_array, ]); } /** * Indicate that no more writes will be sent. */ public function writesDone() { $this->call->startBatch([ OP_SEND_CLOSE_FROM_CLIENT => true, ]); } /** * Wait for the server to send the status, and return it. * * @return \stdClass The status object, with integer $code, string * $details, and array $metadata members */ public function getStatus() { $status_event = $this->call->startBatch([ OP_RECV_STATUS_ON_CLIENT => true, ]); $this->trailing_metadata = $status_event->status->metadata; return $status_event->status; } } PK ! v��͢ � lib/AbstractCall.phpnu ȯ�� <?php /* * * Copyright 2015 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * Class AbstractCall. * @package Grpc */ abstract class AbstractCall { /** * @var Call */ protected $call; protected $deserialize; protected $metadata; protected $trailing_metadata; /** * Create a new Call wrapper object. * * @param Channel $channel The channel to communicate on * @param string $method The method to call on the * remote server * @param callback $deserialize A callback function to deserialize * the response * @param array $options Call options (optional) */ public function __construct(Channel $channel, $method, $deserialize, array $options = []) { if (array_key_exists('timeout', $options) && is_numeric($timeout = $options['timeout']) ) { $now = Timeval::now(); $delta = new Timeval($timeout); $deadline = $now->add($delta); } else { $deadline = Timeval::infFuture(); } $this->call = new Call($channel, $method, $deadline); $this->deserialize = $deserialize; $this->metadata = null; $this->trailing_metadata = null; if (array_key_exists('call_credentials_callback', $options) && is_callable($call_credentials_callback = $options['call_credentials_callback']) ) { $call_credentials = CallCredentials::createFromPlugin( $call_credentials_callback ); $this->call->setCredentials($call_credentials); } } /** * @return mixed The metadata sent by the server */ public function getMetadata() { return $this->metadata; } /** * @return mixed The trailing metadata sent by the server */ public function getTrailingMetadata() { return $this->trailing_metadata; } /** * @return string The URI of the endpoint */ public function getPeer() { return $this->call->getPeer(); } /** * Cancels the call. */ public function cancel() { $this->call->cancel(); } /** * Serialize a message to the protobuf binary format. * * @param mixed $data The Protobuf message * * @return string The protobuf binary format */ protected function _serializeMessage($data) { // Proto3 implementation return $data->serializeToString(); } /** * Deserialize a response value to an object. * * @param string $value The binary value to deserialize * * @return mixed The deserialized value */ protected function _deserializeResponse($value) { if ($value === null) { return; } list($className, $deserializeFunc) = $this->deserialize; $obj = new $className(); $obj->mergeFromString($value); return $obj; } /** * Set the CallCredentials for the underlying Call. * * @param CallCredentials $call_credentials The CallCredentials object */ public function setCallCredentials($call_credentials) { $this->call->setCredentials($call_credentials); } } PK ! ��к= = lib/ServerCallReader.phpnu ȯ�� <?php /* * * Copyright 2020 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * This is an experimental and incomplete implementation of gRPC server * for PHP. APIs are _definitely_ going to be changed. * * DO NOT USE in production. */ class ServerCallReader { public function __construct($call, string $request_type) { $this->call_ = $call; $this->request_type_ = $request_type; } public function read() { $event = $this->call_->startBatch([ OP_RECV_MESSAGE => true, ]); if ($event->message === null) { return null; } $data = new $this->request_type_; $data->mergeFromString($event->message); return $data; } private $call_; private $request_type_; } PK ! �IC� � lib/DefaultCallInvoker.phpnu ȯ�� <?php /* * * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ namespace Grpc; /** * Default call invoker in the gRPC stub. */ class DefaultCallInvoker implements CallInvoker { public function createChannelFactory($hostname, $opts) { return new Channel($hostname, $opts); } public function UnaryCall($channel, $method, $deserialize, $options) { return new UnaryCall($channel, $method, $deserialize, $options); } public function ClientStreamingCall($channel, $method, $deserialize, $options) { return new ClientStreamingCall($channel, $method, $deserialize, $options); } public function ServerStreamingCall($channel, $method, $deserialize, $options) { return new ServerStreamingCall($channel, $method, $deserialize, $options); } public function BidiStreamingCall($channel, $method, $deserialize, $options) { return new BidiStreamingCall($channel, $method, $deserialize, $options); } } PK ! ���� � WaitTimeCalculator.phpnu ȯ�� <?php namespace Laravel\Horizon; use Illuminate\Contracts\Queue\Factory as QueueFactory; use Illuminate\Support\Str; use Laravel\Horizon\Contracts\MetricsRepository; use Laravel\Horizon\Contracts\SupervisorRepository; class WaitTimeCalculator { /** * The queue factory implementation. * * @var \Illuminate\Contracts\Queue\Factory */ public $queue; /** * The supervisor repository implementation. * * @var \Laravel\Horizon\Contracts\SupervisorRepository */ public $supervisors; /** * The metrics repository implementation. * * @var \Laravel\Horizon\Contracts\MetricsRepository */ public $metrics; /** * Create a new calculator instance. * * @param \Illuminate\Contracts\Queue\Factory $queue * @param \Laravel\Horizon\Contracts\SupervisorRepository $supervisors * @param \Laravel\Horizon\Contracts\MetricsRepository $metrics * @return void */ public function __construct(QueueFactory $queue, SupervisorRepository $supervisors, MetricsRepository $metrics) { $this->queue = $queue; $this->metrics = $metrics; $this->supervisors = $supervisors; } /** * Calculate the time to clear a given queue in seconds. * * @param string $queue * @return float */ public function calculateFor($queue) { return array_values($this->calculate($queue))[0] ?? 0; } /** * Calculate the time to clear per queue in seconds. * * @param string|null $queue * @return array */ public function calculate($queue = null) { $queues = $this->queueNames( $supervisors = collect($this->supervisors->all()), $queue ); return $queues->mapWithKeys(function ($queue) use ($supervisors) { $totalProcesses = $this->totalProcessesFor($supervisors, $queue); [$connection, $queueName] = explode(':', $queue, 2); return [$queue => $this->calculateTimeToClear($connection, $queueName, $totalProcesses)]; })->sort()->reverse()->all(); } /** * Get all of the queue names. * * @param \Illuminate\Support\Collection $supervisors * @param string|null $queue * @return \Illuminate\Support\Collection */ protected function queueNames($supervisors, $queue = null) { $queues = $supervisors->map(function ($supervisor) { return array_keys($supervisor->processes); })->collapse()->unique()->values(); return $queue ? $queues->intersect([$queue]) : $queues; } /** * Get the total process count for a given queue. * * @param \Illuminate\Support\Collection $allSupervisors * @param string $queue * @return int */ protected function totalProcessesFor($allSupervisors, $queue) { return $allSupervisors->sum(function ($supervisor) use ($queue) { return $supervisor->processes[$queue] ?? 0; }); } /** * Calculate the time to clear for the given queue in seconds distributed over the given amount of processes. * * @param string $connection * @param string $queue * @param int $totalProcesses * @return int */ public function calculateTimeToClear($connection, $queue, $totalProcesses) { $timeToClear = ! Str::contains($queue, ',') ? $this->timeToClearFor($connection, $queue) : collect(explode(',', $queue))->sum(function ($queueName) use ($connection) { return $this->timeToClearFor($connection, $queueName); }); return $totalProcesses === 0 ? round($timeToClear / 1000) : round(($timeToClear / $totalProcesses) / 1000); } /** * Get the total time to clear (in milliseconds) for a given queue. * * @param string $connection * @param string $queue * @return float */ protected function timeToClearFor($connection, $queue) { $size = $this->queue->connection($connection)->readyNow($queue); return $size * $this->metrics->runtimeForQueue($queue); } } PK ! ��5M M "