bpolaszek /
mercure-php-hub
| 1 | <?php |
||||
| 2 | |||||
| 3 | namespace BenTools\MercurePHP\Command; |
||||
| 4 | |||||
| 5 | use Lcobucci\JWT\Builder; |
||||
| 6 | use Lcobucci\JWT\Signer\Hmac\Sha256; |
||||
| 7 | use Lcobucci\JWT\Signer\Key; |
||||
| 8 | use RingCentral\Psr7\Uri; |
||||
| 9 | use Symfony\Component\Console\Command\Command; |
||||
| 10 | use Symfony\Component\Console\Input\InputArgument; |
||||
| 11 | use Symfony\Component\Console\Input\InputInterface; |
||||
| 12 | use Symfony\Component\Console\Input\InputOption; |
||||
| 13 | use Symfony\Component\Console\Output\OutputInterface; |
||||
| 14 | use Symfony\Component\Console\Style\SymfonyStyle; |
||||
| 15 | use Symfony\Component\HttpClient\Exception\TimeoutException; |
||||
| 16 | use Symfony\Component\HttpClient\Exception\TransportException; |
||||
| 17 | use Symfony\Component\HttpClient\HttpClient; |
||||
| 18 | use Symfony\Contracts\HttpClient\HttpClientInterface; |
||||
| 19 | |||||
| 20 | final class StressSubscribersCommand extends Command |
||||
| 21 | { |
||||
| 22 | protected static $defaultName = 'mercure:stress:subscribers'; |
||||
| 23 | |||||
| 24 | protected function execute(InputInterface $input, OutputInterface $output): int |
||||
| 25 | { |
||||
| 26 | $output = new SymfonyStyle($input, $output); |
||||
| 27 | $start = time(); |
||||
| 28 | |||||
| 29 | if (null === $input->getOption('jwt-key')) { |
||||
| 30 | $output->error('No jwt-key provided.'); |
||||
| 31 | |||||
| 32 | return 1; |
||||
| 33 | } |
||||
| 34 | |||||
| 35 | if (null === $input->getOption('topics')) { |
||||
| 36 | $output->error('No topics provided.'); |
||||
| 37 | |||||
| 38 | return 1; |
||||
| 39 | } |
||||
| 40 | |||||
| 41 | $jwt = (new Builder()) |
||||
| 42 | ->withClaim('mercure', ['subscribe' => ['*']]) |
||||
| 43 | ->getToken(new Sha256(), new Key($input->getOption('jwt-key'))); |
||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
| 44 | |||||
| 45 | $client = HttpClient::create( |
||||
| 46 | [ |
||||
| 47 | 'http_version' => '2.0', |
||||
| 48 | 'verify_peer' => false, |
||||
| 49 | 'verify_host' => false, |
||||
| 50 | 'headers' => [ |
||||
| 51 | 'Authorization' => 'Bearer ' . $jwt, |
||||
| 52 | ], |
||||
| 53 | ] |
||||
| 54 | ); |
||||
| 55 | |||||
| 56 | $url = new Uri($input->getArgument('url')); |
||||
|
0 ignored issues
–
show
It seems like
$input->getArgument('url') can also be of type string[]; however, parameter $uri of RingCentral\Psr7\Uri::__construct() does only seem to accept string, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 57 | $qs = ''; |
||||
| 58 | $topics = \explode(',', $input->getOption('topics')); |
||||
| 59 | foreach ($topics as $topic) { |
||||
| 60 | $qs .= '&topic=' . $topic; |
||||
| 61 | } |
||||
| 62 | |||||
| 63 | $url = $url->withQuery($qs); |
||||
| 64 | $nbSubscribers = (int) $input->getOption('subscribers'); |
||||
| 65 | |||||
| 66 | $requests = function (HttpClientInterface $client, string $url) use ($nbSubscribers) { |
||||
| 67 | for ($i = 0; $i < $nbSubscribers; $i++) { |
||||
| 68 | yield $client->request('GET', $url); |
||||
| 69 | } |
||||
| 70 | }; |
||||
| 71 | |||||
| 72 | $duration = (int) $input->getOption('duration'); |
||||
| 73 | $times = []; |
||||
| 74 | try { |
||||
| 75 | foreach ($client->stream($requests($client, $url), $duration) as $response => $chunk) { |
||||
| 76 | $now = \time(); |
||||
| 77 | $times[$now] ??= 0; |
||||
| 78 | $times[$now]++; |
||||
| 79 | |||||
| 80 | if ($now >= ($start + $duration)) { |
||||
| 81 | $response->cancel(); |
||||
| 82 | } |
||||
| 83 | } |
||||
| 84 | } catch (TimeoutException | TransportException $e) { |
||||
|
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
|
|||||
| 85 | } |
||||
| 86 | |||||
| 87 | $average = (int) \round(\array_sum($times) / \count($times)); |
||||
| 88 | $output->success(\sprintf('Average messages /sec: %d', $average)); |
||||
| 89 | |||||
| 90 | return 0; |
||||
| 91 | } |
||||
| 92 | |||||
| 93 | protected function configure(): void |
||||
| 94 | { |
||||
| 95 | $this->setDescription('(Testing purposes) Simulates n subscribers on a Mercure Hub.'); |
||||
| 96 | $this->addArgument('url', InputArgument::REQUIRED, 'Mercure Hub url.'); |
||||
| 97 | $this->addOption('jwt-key', null, InputOption::VALUE_REQUIRED, 'Subscriber JWT KEY.'); |
||||
| 98 | $this->addOption('topics', null, InputOption::VALUE_REQUIRED, 'Topics to subscribe, comma-separated.'); |
||||
| 99 | $this->addOption('duration', null, InputOption::VALUE_OPTIONAL, 'Duration of the test, in seconds.', 10); |
||||
| 100 | $this->addOption('subscribers', null, InputOption::VALUE_OPTIONAL, 'Number of subscribers', 100); |
||||
| 101 | } |
||||
| 102 | } |
||||
| 103 |