-
Notifications
You must be signed in to change notification settings - Fork 13
Description
First, a few sentences of what I am trying to do:
I want to use "Local Evaluation"
Each time I want to get flags for users, I would like to hit the cache always.
There will be a cron job that will call an API endpoint in my code, which will update the cache with new data every X
interval. (so end users don't experience lag)
Here is what I did
If I have a index.php
file:
<?php
$startTime = microtime(true);
$featureFlags = new FeatureFlags();
$userFeatureFlags = $featureFlags->forUser();
$endTime = microtime(true);
$executionTime = number_format($endTime - $startTime, 6);
var_dump($executionTime);
echo "<br>";
var_dump($userFeatureFlags);
die();
And a FeatureFlags class that looks like this:
<?php
use Flagsmith\Flagsmith;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Psr16Cache;
class FeatureFlags {
private Flagsmith $flagsmith;
function __construct() {
$this->flagsmith = (new Flagsmith('SERVER_API_KEY', null, null, 10))
->withCache(new Psr16Cache(new FilesystemAdapter('featureFlagsCache')));
$this->flagsmith->updateEnvironment();
}
function forUser() {
$allIdentityFlags = $this->flagsmith->getIdentityFlags("1", (object) [
'instanceType' => "SomeThing"
])->flags;
return $allIdentityFlags;
}
}
- I did install
composer require flagsmith/flagsmith-php-client guzzlehttp/guzzle symfony/cache
Case 1 (Works, but has latency due to a blocking request to Flagsmith if cache is stale)
when we call ->updateEnvironment()
after the new Flagsmith
if the cache expired, a request is made to Flagsmith and the response will update the cache successfully.
function __construct() {
$this->flagsmith = (new Flagsmith('SERVER_API_KEY', null, null, 10))
->withCache(new Psr16Cache(new FilesystemAdapter('featureFlagsCache')));
$this->flagsmith->updateEnvironment();
}
This is fine, but after the cache expires, the next user visiting the page will experience a slower response.
I want to remove the blocking API call to Flagsmith,
by introducing a cron job that will update the cache.
Lets see tha Case 2.
Case 2 (doesn't work, but no latency because the API Flagsmith was moved to a cron job)
I have created an API endpoint POST /invalidate-cache
, where I do:
// this is what the /invalidate-cache call does
$featureFlags = new FeatureFlags();
$featureFlags->flagsmith->updateEnvironment();
A cron process will call that API every 60 seconds.
<?php
use Flagsmith\Flagsmith;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Psr16Cache;
class FeatureFlags {
public Flagsmith $flagsmith;
function __construct() {
- $this->flagsmith = (new Flagsmith('SERVER_API_KEY', null, null, 10))
+ $this->flagsmith = (new Flagsmith('SERVER_API_KEY', null, null, 1)) // need to provide environmentTtl for localEvaluation to be `true`, but I reduced it to 1 second
->withCache(new Psr16Cache(new FilesystemAdapter('featureFlagsCache')));
- $this->flagsmith->updateEnvironment();
}
function forUser() {
$allIdentityFlags = $this->flagsmith->getIdentityFlags("1", (object) [
'instanceType' => "SomeThing"
])->flags;
return $allIdentityFlags;
}
}
I have noticed that this doesn't work, and by that I mean:
- On the Flagsmith dashboard, there is a flag
"myFlag"
disabled
. - user_1 lands on the page, because there was no cache, FlagSmith API will be called and the response will be put in the cache with the value
"myFlag" disabled
- user_2 lands on the page, because there is a cache now, the response for him will be fast. And the cache will contain
"myFlag" disabled
. - Admin changes the flag in the dashboard and now
"myFlag"
isenabled
. - user_3 lands on the page, because there is cache now, the response for him will be fast. and the cache will contain
"myFlag" disabled
- cron job call
POST /invalidate-cache
because we specified1
forenvironmentTtl
the php should make a call to the Flagsmith api and put the response in the cache, and the cache should have the value"myFlag" enabled
- user_3 lands on the page, because there is cache now, the response for him will be fast. and the cache:
Expected:
should contain"myFlag" enabled
Actual:
it contains"myFlag" disabled
Question:
If I have:
class FeatureFlags {
function __construct() {
$this->flagsmith = (new Flagsmith('SERVER_API_KEY', null, null, 1))
->withCache(new Psr16Cache(new FilesystemAdapter('featureFlagsCache')));
}
}
and later, in some API endpoint, call:
$featureFlags = new FeatureFlags();
$featureFlags->flagsmith->updateEnvironment();
Given that environmentTtl will have a value of 1
That should cause the cache to be considered stale immediately.
so next time we call flagsmith->updateEnvironment();
from an API (like POST /invalidate-cache
),
I would expect the Flagsmith API to be called and that the response to be put in cache, so the cache will contain fresh data...
function forUser() {
$allIdentityFlags = $this->flagsmith->getIdentityFlags("1", (object) [
'instanceType' => "SomeThing"
])->flags;
return $allIdentityFlags;
}
It doesn't function like that currently,
the cache, for unknown reasons, still contains old data.
flagsmith-php-client version: v4.4.0