Flagsmith / Flagsmith/flagsmith-php-client

Cache doesn't get updated in [Case 2]

Đang mở
#100 4 bình luận 0 reaction 0 người được giao Xem trên GitHub
bug
Ngôn ngữ chính
PHP
Star
18
Fork
13
Merge trung bình
28 phút
Pull request đã merge (30 ngày)
1

Mô tả

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**

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Hướng nghiên cứu

Bắt đầu bằng cách lần theo constructor của PHP client của Flagsmith, cách xử lý environmentTtl và updateEnvironment với Psr16Cache và FilesystemAdapter của Symfony. Tái hiện luồng POST /invalidate-cache từ issue, sau đó kiểm tra xem environment được cache có thay đổi sau TTL hay không; hoàn tất khi bản cập nhật được cron kích hoạt lưu flag đã bật cho những người dùng tiếp theo.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
php, symfony
Lĩnh vực
backend
Loại issue
Lỗi
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.