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
![]() |
|||||
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
![]() |
|||||
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 |