Skip to content

Commit

Permalink
Merge pull request #21 from splitio/task/flagSetsCache
Browse files Browse the repository at this point in the history
Added cache methods for flagSets
  • Loading branch information
mmelograno authored Jan 15, 2024
2 parents d9a8934 + 91b2a6d commit 8abebc2
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 7 deletions.
45 changes: 38 additions & 7 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ public function getTreatmentsWithConfig(string $key, ?string $bucketingKey, arra
$this->tracer->trace(TEF::forStart($method, $id, $this->tracer->includeArgs() ? func_get_args() : []));
$toReturn = $this->cache->getManyWithConfig($key, $features, $attributes);
$features = self::getMissing($toReturn);

if (count($features) == 0) {
return $toReturn;
}
Expand Down Expand Up @@ -166,7 +165,14 @@ public function getTreatmentsByFlagSet(
$id = $this->tracer->makeId();
$method = Tracer::METHOD_GET_TREATMENTS_BY_FLAG_SET;
$this->tracer->trace(TEF::forStart($method, $id, $this->tracer->includeArgs() ? func_get_args() : []));
// @TODO implement cache for this method
$featuresFromSet = $this->cache->getFeaturesByFlagSets([$flagSet]);
if (!is_null($featuresFromSet)) {
$toReturn = $this->cache->getMany($key, $featuresFromSet, $attributes);
$features = self::getMissing($toReturn);
if (count($features) == 0) {
return $toReturn;
}
}

$this->tracer->trace(TEF::forRPCStart($method, $id));
$results = $this->lm->getTreatmentsByFlagSet($key, $bucketingKey, $flagSet, $attributes);
Expand All @@ -176,6 +182,7 @@ public function getTreatmentsByFlagSet(
$toReturn[$feature] = $treatment;
$this->handleListener($key, $bucketingKey, $feature, $attributes, $treatment, $ilData);
}
$this->cache->setFeaturesForFlagSets([$flagSet], array_keys($results));
$this->cache->setMany($key, $attributes, $toReturn);
return $toReturn;
} catch (\Exception $exc) {
Expand All @@ -197,7 +204,14 @@ public function getTreatmentsWithConfigByFlagSet(
$id = $this->tracer->makeId();
$method = Tracer::METHOD_GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET;
$this->tracer->trace(TEF::forStart($method, $id, $this->tracer->includeArgs() ? func_get_args() : []));
// @TODO implement cache for this method
$featuresFromSet = $this->cache->getFeaturesByFlagSets([$flagSet]);
if (!is_null($featuresFromSet)) {
$toReturn = $this->cache->getManyWithConfig($key, $featuresFromSet, $attributes);
$features = self::getMissing($toReturn);
if (count($features) == 0) {
return $toReturn;
}
}

$this->tracer->trace(TEF::forRPCStart($method, $id));
$results = $this->lm->getTreatmentsWithConfigByFlagSet($key, $bucketingKey, $flagSet, $attributes);
Expand All @@ -207,7 +221,8 @@ public function getTreatmentsWithConfigByFlagSet(
$toReturn[$feature] = ['treatment' => $treatment, 'config' => $config];
$this->handleListener($key, $bucketingKey, $feature, $attributes, $treatment, $ilData);
}
$this->cache->setMany($key, $attributes, $toReturn);
$this->cache->setFeaturesForFlagSets([$flagSet], array_keys($results));
$this->cache->setManyWithConfig($key, $attributes, $toReturn);
return $toReturn;
} catch (\Exception $exc) {
$this->tracer->trace(TEF::forException($method, $id, $exc));
Expand All @@ -228,7 +243,14 @@ public function getTreatmentsByFlagSets(
$id = $this->tracer->makeId();
$method = Tracer::METHOD_GET_TREATMENTS_BY_FLAG_SETS;
$this->tracer->trace(TEF::forStart($method, $id, $this->tracer->includeArgs() ? func_get_args() : []));
// @TODO implement cache for this method
$featuresFromSets = $this->cache->getFeaturesByFlagSets($flagSets);
if (!is_null($featuresFromSets)) {
$toReturn = $this->cache->getMany($key, $featuresFromSets, $attributes);
$features = self::getMissing($toReturn);
if (count($features) == 0) {
return $toReturn;
}
}

$this->tracer->trace(TEF::forRPCStart($method, $id));
$results = $this->lm->getTreatmentsByFlagSets($key, $bucketingKey, $flagSets, $attributes);
Expand All @@ -238,6 +260,7 @@ public function getTreatmentsByFlagSets(
$toReturn[$feature] = $treatment;
$this->handleListener($key, $bucketingKey, $feature, $attributes, $treatment, $ilData);
}
$this->cache->setFeaturesForFlagSets($flagSets, array_keys($results));
$this->cache->setMany($key, $attributes, $toReturn);
return $toReturn;
} catch (\Exception $exc) {
Expand All @@ -259,7 +282,14 @@ public function getTreatmentsWithConfigByFlagSets(
$id = $this->tracer->makeId();
$method = Tracer::METHOD_GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS;
$this->tracer->trace(TEF::forStart($method, $id, $this->tracer->includeArgs() ? func_get_args() : []));
// @TODO implement cache for this method
$featuresFromSet = $this->cache->getFeaturesByFlagSets($flagSets);
if (!is_null($featuresFromSet)) {
$toReturn = $this->cache->getManyWithConfig($key, $featuresFromSet, $attributes);
$features = self::getMissing($toReturn);
if (count($features) == 0) {
return $toReturn;
}
}

$this->tracer->trace(TEF::forRPCStart($method, $id));
$results = $this->lm->getTreatmentsWithConfigByFlagSets($key, $bucketingKey, $flagSets, $attributes);
Expand All @@ -269,7 +299,8 @@ public function getTreatmentsWithConfigByFlagSets(
$toReturn[$feature] = ['treatment' => $treatment, 'config' => $config];
$this->handleListener($key, $bucketingKey, $feature, $attributes, $treatment, $ilData);
}
$this->cache->setMany($key, $attributes, $toReturn);
$this->cache->setFeaturesForFlagSets($flagSets, array_keys($results));
$this->cache->setManyWithConfig($key, $attributes, $toReturn);
return $toReturn;
} catch (\Exception $exc) {
$this->tracer->trace(TEF::forException($method, $id, $exc));
Expand Down
2 changes: 2 additions & 0 deletions src/Utils/EvalCache/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ public function get(string $key, string $feature, ?array $attributes): ?string;
public function getMany(string $key, array $features, ?array $attributes): array;
public function getWithConfig(string $key, string $feature, ?array $attributes): ?array;
public function getManyWithConfig(string $key, array $features, ?array $attributes): array;
public function getFeaturesByFlagSets(array $flagSets): ?array;
public function set(string $key, string $feature, ?array $attributes, string $treatment);
public function setMany(string $key, ?array $attributes, array $results);
public function setWithConfig(string $key, string $feature, ?array $attributes, string $treatment, ?string $config);
public function setManyWithConfig(string $key, ?array $attributes, array $results);
public function setFeaturesForFlagSets(array $flagSets, array $featuresFlags);
}
14 changes: 14 additions & 0 deletions src/Utils/EvalCache/CacheImpl.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class CacheImpl implements Cache
private /*array*/ $data;
private /*InputHasher*/ $hasher;
private /*EvictionPolicy*/ $evictionPolicy;
private /*array*/ $flagSets;

public function __construct(InputHasher $hasher, EvictionPolicy $evictionPolicy)
{
Expand Down Expand Up @@ -50,6 +51,12 @@ public function getManyWithConfig(string $key, array $features, ?array $attribut
return $result;
}

public function getFeaturesByFlagSets(array $flagSets): ?array
{
sort($flagSets); // Order flagSets to grab from store
$h = implode(",", $flagSets); // Concatenating each flagSet with a comma e.g: flagSet1,flagSet2,flagSet3
return $this->flagSets[$h] ?? null;
}
public function set(string $key, string $feature, ?array $attributes, string $treatment)
{
$h = $this->hasher->hashInput($key, $feature, $attributes);
Expand Down Expand Up @@ -78,6 +85,13 @@ public function setManyWithConfig(string $key, ?array $attributes, array $result
}
}

public function setFeaturesForFlagSets(array $flagSets, array $featuresFlags)
{
sort($flagSets); // Order flagSets to store
$h = implode(",", $flagSets); // Concatenating each flagSet with a comma e.g: flagSet1,flagSet2,flagSet3
$this->flagSets[$h] = $featuresFlags;
}

private function _get(string $key, string $feature, ?array $attributes): ?Entry
{
$h = $this->hasher->hashInput($key, $feature, $attributes);
Expand Down
9 changes: 9 additions & 0 deletions src/Utils/EvalCache/NoCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public function getManyWithConfig(string $key, array $features, ?array $attribut
return $res;
}

public function getFeaturesByFlagSets(array $flagSets): ?array
{
return null;
}

public function set(string $key, string $feature, ?array $attributes, string $treatment)
{
}
Expand All @@ -47,4 +52,8 @@ public function setWithConfig(string $key, string $feature, ?array $attributes,
public function setManyWithConfig(string $key, ?array $attributes, array $results)
{
}

public function setFeaturesForFlagSets(array $flagSets, array $featuresFlags)
{
}
}
8 changes: 8 additions & 0 deletions tests/Utils/EvalCache/CacheImplTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,12 @@ public function testWithConfig()
// nothing matches for [] attributes
$this->assertEquals(['f1' => null, 'f2' => null, 'f3' => null], $c->getManyWithConfig('key', ['f1', 'f2', 'f3'], []));
}

public function testByFlagSets()
{
$c = new CacheImpl(new KeyAttributeCRC32Hasher(), new NoEviction(0));
$c->setFeaturesForFlagSets(['s2', 's1'], ['f1', 'f2']);
$this->assertEquals(['f1', 'f2'], $c->getFeaturesByFlagSets(['s1', 's2']));
$this->assertEquals(['f1', 'f2'], $c->getFeaturesByFlagSets(['s2', 's1']));
}
}
4 changes: 4 additions & 0 deletions tests/Utils/EvalCache/NoCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,9 @@ public function testNoCache()
$this->assertEquals(null, $c->getWithConfig('key', 'f1', null));
$this->assertEquals(null, $c->getWithConfig('key', 'f2', null));
$this->assertEquals(['f1' => null, 'f2' => null], $c->getManyWithConfig('key', ['f1', 'f2'], null));

$c->setFeaturesForFlagSets(['s1', 's2'], ['f1', 'f2']);
$this->assertEquals(null, $c->getFeaturesByFlagSets(['s1', 's2']));
$this->assertEquals(null, $c->getFeaturesByFlagSets(['s2', 's1']));
}
}

0 comments on commit 8abebc2

Please sign in to comment.