Skip to content

Commit 14f179d

Browse files
author
Anton Shabouta
committed
Auth capabilities and other improvements
1 parent c1380f1 commit 14f179d

14 files changed

+190
-65
lines changed

CHANGELOG.md

-22
This file was deleted.

CONTRIBUTING.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ We accept contributions via Pull Requests on [Github](https://github.com/phpinna
77

88
## Pull Requests
99

10-
- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - Check the code style with ``$ composer check-style`` and fix it with ``$ composer fix-style``.
10+
- **Follow our coding standard.** - It mostly based on [PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md).
1111

1212
- **Add tests!** - Your patch won't be accepted if it does not have tests.
1313

@@ -25,7 +25,7 @@ We accept contributions via Pull Requests on [Github](https://github.com/phpinna
2525
## Running Tests
2626

2727
```bash
28-
$ composer test
28+
$ CASSIS_TEST_DSN=tcp://user:pass@localhost:9042 composer test
2929
```
3030

3131

README.md

+3-7
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use PHPinnacle\Cassis\Statement;
3333
require __DIR__ . '/vendor/autoload.php';
3434

3535
Loop::run(function () {
36-
$cluster = Cluster::build('tcp://admin:admin123@172.23.0.3');
36+
$cluster = Cluster::build('tcp://localhost:9042');
3737

3838
/** @var Session $session */
3939
$session = yield $cluster->connect('system');
@@ -60,14 +60,10 @@ CASSIS_EXAMPLE_DSN=tcp://user:pass@localhost:9042 php example/*
6060
Benchmarks were run as:
6161

6262
```bash
63-
64-
CASSIS_BENCHMARK_DSN=tcp://user:pass@localhost:9042 php benchmark/simple.php N
63+
CASSIS_BENCHMARK_DSN=tcp://user:pass@localhost:9042 php benchmark/write.php N
64+
CASSIS_BENCHMARK_DSN=tcp://user:pass@localhost:9042 php benchmark/read.php N M
6565
```
6666

67-
## Change log
68-
69-
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
70-
7167
## Testing
7268

7369
```bash

benchmark/read.php

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
use Amp\Loop;
4+
use PHPinnacle\Cassis\Context;
5+
use PHPinnacle\Cassis\Session;
6+
use PHPinnacle\Cassis\Cluster;
7+
use PHPinnacle\Cassis\Value;
8+
use Ramsey\Uuid\Uuid;
9+
10+
require_once __DIR__ . '/../vendor/autoload.php';
11+
12+
Loop::run(function () use ($argv) {
13+
if (!$dsn = \getenv('CASSIS_BENCHMARK_DSN')) {
14+
echo 'No benchmark dsn! Please set CASSIS_BENCHMARK_DSN environment variable.', \PHP_EOL;
15+
16+
Loop::stop();
17+
}
18+
19+
$cluster = Cluster::build(\getenv('CASSIS_BENCHMARK_DSN'));
20+
/** @var Session $session */
21+
$session = yield $cluster->connect();
22+
$setup = require __DIR__ . '/shared.php';
23+
24+
$watcher = Loop::onSignal(SIGTERM, function () use ($cluster) {
25+
yield $cluster->disconnect();
26+
});
27+
28+
try {
29+
foreach ($setup as $query) {
30+
yield $session->query($query);
31+
}
32+
33+
$toWrite = $argv[1] ?? 10000;
34+
$toRead = $argv[2] ?? 1000;
35+
36+
$promises = [];
37+
38+
for ($i = 1; $i <= $toWrite; $i++) {
39+
$author = new Value\UserDefined([
40+
'id' => $i,
41+
'name' => "User $i",
42+
'enabled' => (bool) ($i % 2),
43+
]);
44+
45+
$arguments = [
46+
'author' => $author,
47+
'post_id' => Uuid::uuid1(),
48+
'text' => random_string(500),
49+
'date' => Value\Timestamp::fromDateTime(random_date()),
50+
'tags' => Value\Collection::set(random_tags(\rand(1, 10), 5)),
51+
];
52+
53+
$fields = \implode(',', \array_keys($arguments));
54+
$values = \implode(',', \array_fill(0, \count($arguments), '?'));
55+
56+
$promises[] = $session->query("INSERT INTO posts_by_user ($fields) VALUES ($values)", $arguments);
57+
}
58+
59+
yield $promises;
60+
61+
echo \sprintf("Done %d inserts. Start reading...\n", $toWrite);
62+
63+
$time = \microtime(true);
64+
$context = (new Context)->limit($toRead);
65+
$total = 0;
66+
67+
/** @var \PHPinnacle\Cassis\Result\Rows $result */
68+
while ($result = yield $session->query("SELECT * FROM posts_by_user;", [], $context)) {
69+
$count = \count($result);
70+
$total = $total + $count;
71+
72+
echo \sprintf("Read %d rows.\n", $count);
73+
74+
if (!$cursor = $result->cursor()) {
75+
break;
76+
}
77+
78+
$context->offset($cursor);
79+
};
80+
81+
echo \sprintf("Read %d rows in %f seconds.\n", $total, \microtime(true) - $time);
82+
} catch (\Throwable $error) {
83+
echo "Got error: {$error->getMessage()}.\n";
84+
} finally {
85+
yield $session->query("DROP KEYSPACE IF EXISTS blogs;");
86+
}
87+
88+
yield $cluster->disconnect();
89+
90+
Loop::cancel($watcher);
91+
});

benchmark/write.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
Loop::stop();
1616
}
1717

18-
$cluster = Cluster::build(\getenv('CASSIS_EXAMPLE_DSN'));
18+
$cluster = Cluster::build(\getenv('CASSIS_BENCHMARK_DSN'));
1919
/** @var Session $session */
2020
$session = yield $cluster->connect();
2121
$setup = require __DIR__ . '/shared.php';

src/Cluster.php

+22-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use function Amp\call;
1616
use Amp\Promise;
1717
use Amp\Socket;
18+
use Amp\Uri\Uri;
1819

1920
final class Cluster
2021
{
@@ -157,7 +158,7 @@ private function open(): Promise
157158
$compressor = $this->detectCompressor();
158159

159160
foreach ($this->config->hosts() as $host) {
160-
$connection = new Connection($host, $this->streams, $compressor);
161+
$connection = new Connection(new Uri($host), $this->streams, $compressor);
161162

162163
try {
163164
yield $connection->open(
@@ -181,7 +182,26 @@ private function open(): Promise
181182
*/
182183
private function authenticate(): Promise
183184
{
184-
return $this->connection->send(new Request\AuthResponse($this->config->user(), $this->config->password()));
185+
return call(function () {
186+
$request = new Request\AuthResponse(
187+
$this->config->user(),
188+
$this->config->password()
189+
);
190+
191+
/** @var Frame $frame */
192+
$frame = yield $this->connection->send($request);
193+
194+
switch (true) {
195+
case $frame instanceof Response\AuthChallenge:
196+
// TODO
197+
198+
break;
199+
case $frame instanceof Response\AuthSuccess:
200+
break;
201+
default:
202+
throw Exception\ServerException::unexpectedFrame($frame->opcode);
203+
}
204+
});
185205
}
186206

187207
/**

src/Connection.php

+23-12
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,21 @@
1313
namespace PHPinnacle\Cassis;
1414

1515
use function Amp\asyncCall, Amp\call;
16-
use function Amp\Socket\connect;
16+
use Amp\Socket\ClientTlsContext;
17+
use function Amp\Socket\connect, Amp\Socket\cryptoConnect;
1718
use Amp\Deferred;
1819
use Amp\Loop;
1920
use Amp\Promise;
2021
use Amp\Socket\ClientConnectContext;
2122
use Amp\Socket\Socket;
23+
use Amp\Uri\Uri;
2224

2325
final class Connection
2426
{
2527
const WRITE_ROUNDS = 64;
2628

2729
/**
28-
* @var string
30+
* @var Uri
2931
*/
3032
private $uri;
3133

@@ -75,11 +77,11 @@ final class Connection
7577
private $lastWrite = 0;
7678

7779
/**
78-
* @param string $uri
79-
* @param Streams $streams
80-
* @param Compressor $compressor
80+
* @param Uri $uri
81+
* @param Streams $streams
82+
* @param Compressor $compressor
8183
*/
82-
public function __construct(string $uri, Streams $streams, Compressor $compressor)
84+
public function __construct(Uri $uri, Streams $streams, Compressor $compressor)
8385
{
8486
$this->uri = $uri;
8587
$this->streams = $streams;
@@ -137,21 +139,29 @@ public function send(Request $request): Promise
137139
public function open(int $timeout, int $attempts, bool $noDelay): Promise
138140
{
139141
return call(function () use ($timeout, $attempts, $noDelay) {
140-
$context = new ClientConnectContext;
142+
$clientContext = new ClientConnectContext;
141143

142144
if ($attempts > 0) {
143-
$context = $context->withMaxAttempts($attempts);
145+
$clientContext = $clientContext->withMaxAttempts($attempts);
144146
}
145147

146148
if ($timeout > 0) {
147-
$context = $context->withConnectTimeout($timeout);
149+
$clientContext = $clientContext->withConnectTimeout($timeout);
148150
}
149151

150152
if ($noDelay) {
151-
$context = $context->withTcpNoDelay();
153+
$clientContext = $clientContext->withTcpNoDelay();
152154
}
153155

154-
$this->socket = yield connect($this->uri, $context);
156+
$uri = \sprintf('tcp://%s:%d', $this->uri->getHost(), $this->uri->getPort());
157+
158+
if ($this->uri->getScheme() === 'tls') {
159+
$cryptoContext = new ClientTlsContext;
160+
161+
$this->socket = yield cryptoConnect($uri, $clientContext, $cryptoContext);
162+
} else {
163+
$this->socket = yield connect($uri, $clientContext);
164+
}
155165

156166
$this->listen();
157167
});
@@ -210,7 +220,8 @@ private function listen(): void
210220
$this->parser->append($chunk);
211221

212222
while ($frame = $this->parser->parse()) {
213-
if ($frame->stream === -1) {
223+
if ($frame->opcode === Frame::OPCODE_EVENT) {
224+
/** @var Response\Event $frame */
214225
$this->emitter->emit($frame);
215226

216227
continue 2;

src/Context.php

+4-15
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ public function consistencyEachQuorum(): self
172172
*/
173173
public function consistencySerial(): self
174174
{
175-
$this->consistency = self::CONSISTENCY_SERIAL;
175+
$this->flags |= self::FLAG_SERIAL_CONSISTENCY;
176+
$this->serialConsistency = self::CONSISTENCY_SERIAL;
176177

177178
return $this;
178179
}
@@ -182,7 +183,8 @@ public function consistencySerial(): self
182183
*/
183184
public function consistencyLocalSerial(): self
184185
{
185-
$this->consistency = self::CONSISTENCY_LOCAL_SERIAL;
186+
$this->flags |= self::FLAG_SERIAL_CONSISTENCY;
187+
$this->serialConsistency = self::CONSISTENCY_LOCAL_SERIAL;
186188

187189
return $this;
188190
}
@@ -233,19 +235,6 @@ public function offset(string $offset): self
233235
return $this;
234236
}
235237

236-
/**
237-
* @param int $consistency
238-
*
239-
* @return self
240-
*/
241-
public function serialConsistency(int $consistency): self
242-
{
243-
$this->flags |= self::FLAG_SERIAL_CONSISTENCY;
244-
$this->serialConsistency = $consistency;
245-
246-
return $this;
247-
}
248-
249238
/**
250239
* @param int $timestamp
251240
*

src/Exception/ServerException.php

+4
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@
1414

1515
class ServerException extends CassisException
1616
{
17+
public static function unexpectedFrame(int $code): self
18+
{
19+
return new self("Unexpected frame with opcode {$code}.");
20+
}
1721
}

src/Parser.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ private function frame(int $opcode, int $length): Frame
137137
case Frame::OPCODE_AUTHENTICATE:
138138
return new Response\Authenticate($this->frameBuffer->consumeString());
139139
case Frame::OPCODE_AUTH_SUCCESS:
140-
return new Response\AuthSuccess;
140+
return new Response\AuthSuccess($this->frameBuffer->consume($length));
141141
case Frame::OPCODE_RESULT:
142142
return new Response\Result($this->frameBuffer->consumeInt(), $this->frameBuffer->consume($length - 4));
143143
case Frame::OPCODE_ERROR:

src/Request/AuthResponse.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,11 @@ public function __construct(string $user, string $password)
4545
public function write(Buffer $buffer): void
4646
{
4747
$buffer
48-
->appendString($this->user)
49-
->appendString($this->password)
48+
->appendUint(\strlen($this->user) + \strlen($this->password) + 2)
49+
->appendByte(0)
50+
->append($this->user)
51+
->appendByte(0)
52+
->append($this->password)
5053
;
5154
}
5255
}

src/Response/AuthChallenge.php

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
/**
3+
* This file is part of PHPinnacle/Cassis.
4+
*
5+
* (c) PHPinnacle Team <dev@phpinnacle.com>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
declare(strict_types = 1);
12+
13+
namespace PHPinnacle\Cassis\Response;
14+
15+
use PHPinnacle\Cassis\Response;
16+
17+
final class AuthChallenge extends Response
18+
{
19+
public $opcode = self::OPCODE_AUTH_CHALLENGE;
20+
}

0 commit comments

Comments
 (0)