Flagsmith / Flagsmith/flagsmith-php-client

Cache doesn't get updated in [Case 2]

Open
#100 4 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
PHP
Stars
18
Forks
13
Avg merge
28m
Merged PRs (30d)
1

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
forUser();
$endTime = microtime(true);
$executionTime = number_format($endTime - $startTime, 6);

var_dump($executionTime);
echo "
";
var_dump($userFeatureFlags);
die();
```

And a FeatureFlags class that looks like this:
```php
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.

```diff
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:

1. On the Flagsmith dashboard, there is a flag `"myFlag"` `disabled`.
2. 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`
3. 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`.
4. Admin changes the flag in the dashboard and now `"myFlag"` is `enabled`.
5. 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`
6. cron job call `POST /invalidate-cache` because we specified `1` for `environmentTtl` 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`
7. 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**

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.