Skip to content

Commit ffd1c39

Browse files
committed
feat: FeatureRequester requires configured ClientInterface
1 parent 40e93c6 commit ffd1c39

File tree

3 files changed

+50
-74
lines changed

3 files changed

+50
-74
lines changed

src/LaunchDarkly/Impl/Integrations/RedisFeatureRequester.php

Lines changed: 15 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,58 +3,34 @@
33
namespace LaunchDarkly\Impl\Integrations;
44

55
use LaunchDarkly\Integrations;
6-
use Predis\Client;
76
use Predis\ClientInterface;
87

98
class RedisFeatureRequester extends FeatureRequesterBase
109
{
11-
public ?ClientInterface $_connection = null;
12-
public ?array $_redisOptions = null;
13-
public ?string $_prefix;
14-
15-
public function __construct(string $baseUri, string $sdkKey, array $options)
16-
{
10+
private readonly string $prefix;
11+
12+
/**
13+
* @param array<string,mixed> $options
14+
* - `prefix`: namespace prefix to add to all hash keys
15+
*/
16+
public function __construct(
17+
private readonly ClientInterface $connection,
18+
string $baseUri,
19+
string $sdkKey,
20+
array $options
21+
) {
1722
parent::__construct($baseUri, $sdkKey, $options);
18-
19-
$this->_prefix = $options['redis_prefix'] ?? null;
20-
if ($this->_prefix === null || $this->_prefix === '') {
21-
$this->_prefix = Integrations\Redis::DEFAULT_PREFIX;
22-
}
23-
24-
$client = $options['predis_client'] ?? null;
25-
if ($client instanceof ClientInterface) {
26-
$this->_connection = $client;
27-
} else {
28-
$this->_redisOptions = [
29-
"scheme" => "tcp",
30-
"timeout" => $options['redis_timeout'] ?? 5,
31-
"host" => $options['redis_host'] ?? 'localhost',
32-
"port" => $options['redis_port'] ?? 6379
33-
];
34-
35-
$this->_redisOptions = array_merge($this->_redisOptions, $options['predis_options'] ?? []);
36-
}
23+
$this->prefix = $options['prefix'] ?? Integrations\Redis::DEFAULT_PREFIX;
3724
}
3825

3926
protected function readItemString(string $namespace, string $key): ?string
4027
{
41-
$redis = $this->getConnection();
42-
return $redis->hget("$this->_prefix:$namespace", $key);
28+
return $this->connection->hget("$this->prefix:$namespace", $key);
4329
}
4430

4531
protected function readItemStringList(string $namespace): ?array
4632
{
47-
$redis = $this->getConnection();
48-
$raw = $redis->hgetall("$this->_prefix:$namespace");
33+
$raw = $this->connection->hgetall("$this->prefix:$namespace");
4934
return $raw ? array_values($raw) : null;
5035
}
51-
52-
protected function getConnection(): ClientInterface
53-
{
54-
if ($this->_connection == null) {
55-
$this->_connection = new Client($this->_redisOptions);
56-
}
57-
58-
return $this->_connection;
59-
}
6036
}

src/LaunchDarkly/Integrations/Redis.php

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
namespace LaunchDarkly\Integrations;
44

5-
use LaunchDarkly\Impl\Integrations\RedisFeatureRequester;
65
use LaunchDarkly\Impl\Integrations\RedisBigSegmentsStore;
6+
use LaunchDarkly\Impl\Integrations\RedisFeatureRequester;
77
use LaunchDarkly\Subsystems;
88
use Predis\ClientInterface;
99
use Psr\Log\LoggerInterface;
@@ -20,39 +20,29 @@ class Redis
2020
*
2121
* After calling this method, store its return value in the `feature_requester` property of your client configuration:
2222
*
23-
* $fr = LaunchDarkly\Integrations\Redis::featureRequester([ "redis_prefix" => "env1" ]);
24-
* $config = [ "feature_requester" => $fr ];
23+
* $fr = LaunchDarkly\Integrations\Redis::featureRequester(["prefix" => "env1"]);
24+
* $config = ["feature_requester" => $fr];
2525
* $client = new LDClient("sdk_key", $config);
2626
*
2727
* For more about using LaunchDarkly with databases, see the
2828
* [SDK reference guide](https://docs.launchdarkly.com/sdk/features/storing-data).
2929
*
30-
* @param array $options Configuration settings (can also be passed in the main client configuration):
31-
* - `redis_host`: hostname of the Redis server; defaults to `localhost`
32-
* - `redis_port`: port of the Redis server; defaults to 6379
33-
* - `redis_timeout`: connection timeout in seconds; defaults to 5
34-
* - `redis_prefix`: a string to be prepended to all database keys; corresponds to the prefix
35-
* setting in ld-relay
36-
* - `predis_client`: an already-configured Predis client instance if you wish to reuse one; if
37-
* specified, this will cause all other options except `redis_prefix` and `apc_expiration`
38-
* to be ignored
39-
* - `predis_options`: an array of connection options to be passed directly to the Predis client;
40-
* these can include any options supported by `Predis\Client`, and will override any equivalent
41-
* top-level options (for instance, `"host"` in `predis_options` takes priority over `"redis_host"`
42-
* at the top level)
43-
* - `apc_expiration`: expiration time in seconds for local caching, if `APCu` is installed
44-
* @return mixed an object to be stored in the `feature_requester` configuration property
30+
* @param array<string, mixed> $options Configuration settings (can also be passed in the main client configuration):
31+
* - `prefix`: a string to be prepended to all database keys; corresponds
32+
* to the prefix setting in ld-relay
33+
* @return callable(string, string, array): Subsystems\FeatureRequester
4534
*/
46-
public static function featureRequester(array $options = [])
35+
public static function featureRequester(ClientInterface $client, array $options = []): callable
4736
{
48-
return function (string $baseUri, string $sdkKey, array $baseOptions) use ($options) {
49-
return new RedisFeatureRequester($baseUri, $sdkKey, array_merge($baseOptions, $options));
37+
return function (string $baseUri, string $sdkKey, array $baseOptions) use ($client, $options): Subsystems\FeatureRequester {
38+
return new RedisFeatureRequester($client, $baseUri, $sdkKey, array_merge($baseOptions, $options));
5039
};
5140
}
5241

5342
/**
5443
* @param array<string,mixed> $options
55-
* - `prefix`: namespace prefix to add to all hash keys
44+
* - `prefix`: a string to be prepended to all database keys; corresponds
45+
* to the prefix setting in ld-relay
5646
* @return callable(LoggerInterface, array): Subsystems\BigSegmentsStore
5747
*/
5848
public static function bigSegmentsStore(ClientInterface $client, array $options = []): callable

tests/DatabaseFeatureRequesterTestBase.php

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ protected function putSerializedItem(
5454
string $namespace,
5555
string $key,
5656
int $version,
57-
string $json): void
58-
{
57+
string $json
58+
): void {
5959
throw new \RuntimeException("test class did not implement putSerializedItem");
6060
}
6161

@@ -149,7 +149,7 @@ public function testAllFeaturesWithEmptyStore(?string $prefix): void
149149
$fr = $this->makeRequester($prefix);
150150

151151
$flags = $fr->getAllFeatures();
152-
$this->assertEquals(array(), $flags);
152+
$this->assertEquals([], $flags);
153153
}
154154

155155
/**
@@ -228,10 +228,20 @@ public function testPrefixIndependence(): void
228228
private function setupForPrefix(?string $prefix, string $flagKey, string $segmentKey, int $flagVersion): void
229229
{
230230
$segmentVersion = $flagVersion * 2;
231-
$this->putSerializedItem($prefix, 'features', $flagKey, $flagVersion,
232-
self::makeFlagJson($flagKey, $flagVersion));
233-
$this->putSerializedItem($prefix, 'segments', $segmentKey, $segmentVersion,
234-
self::makeSegmentJson($flagKey, $segmentVersion));
231+
$this->putSerializedItem(
232+
$prefix,
233+
'features',
234+
$flagKey,
235+
$flagVersion,
236+
self::makeFlagJson($flagKey, $flagVersion)
237+
);
238+
$this->putSerializedItem(
239+
$prefix,
240+
'segments',
241+
$segmentKey,
242+
$segmentVersion,
243+
self::makeSegmentJson($flagKey, $segmentVersion)
244+
);
235245
}
236246

237247
private function verifyForPrefix($fr, string $flagKey, string $segmentKey, int $flagVersion): void
@@ -265,7 +275,7 @@ public function prefixParameters(): array
265275

266276
private static function makeFlagJson(string $key, int $version, bool $deleted = false): string|bool
267277
{
268-
return json_encode(array(
278+
return json_encode([
269279
'key' => $key,
270280
'version' => $version,
271281
'on' => true,
@@ -282,19 +292,19 @@ private static function makeFlagJson(string $key, int $version, bool $deleted =
282292
false,
283293
],
284294
'deleted' => $deleted
285-
));
295+
]);
286296
}
287297

288298
private static function makeSegmentJson(string $key, int $version, bool $deleted = false): string|bool
289299
{
290-
return json_encode(array(
300+
return json_encode([
291301
'key' => $key,
292302
'version' => $version,
293-
'included' => array(),
294-
'excluded' => array(),
303+
'included' => [],
304+
'excluded' => [],
295305
'rules' => [],
296306
'salt' => '',
297307
'deleted' => $deleted
298-
));
308+
]);
299309
}
300310
}

0 commit comments

Comments
 (0)