Skip to content

Conversation

@hussonkevin
Copy link

I have to define my own TTL cache (via guzzle) so I need to use a different CacheStrategyInterface (GreedyCacheStrategy and not PublicCacheStrategy)

Example of use :

return new LDClient(config('services.launchdarkly.key'), [
    'timeout'           => 3,
    'connect_timeout'   => 3,
    // cache redis
    'cache'             => new GreedyCacheStrategy(
        new LaravelCacheStorage(
            \Cache::store('redis')
        ),
        3600
    ),
]);

Can you accept this PR as soon as possible please ? (we need to put it in production)

@eli-darkly
Copy link
Contributor

Could you say more about why you need to use a GreedyCacheStrategy? The comments on that class say:

It can be used to cache responses in spite of any cache related response headers, but it SHOULDN'T be used unless absolutely necessary, e.g. when accessing badly designed APIs without Cache control.

The LaunchDarkly service endpoints do provide cache-related response headers, which are determined by the TTL setting on the LD dashboard. A cache that deliberately ignores those headers is contrary to the intended use.

@hussonkevin
Copy link
Author

My bad... it works on a new created environment with the headers and the TTL defined. Thanks you for your reactivity and sorry for that PR

@hussonkevin hussonkevin closed this Aug 5, 2020
@eli-darkly
Copy link
Contributor

No problem - glad it's working.

@dionkimAXS
Copy link

dionkimAXS commented Jun 29, 2022

@eli-darkly, have there been any other reports of this issue recently?
we are using the sdk with the following packages
"launchdarkly/server-sdk": "3.9.1", "guzzlehttp/guzzle": "^6.3.0", "kevinrob/guzzle-cache-middleware": "1.4.0."
and it seems like we are experiencing this exact issue.

i set the TTL on the environment to be 60 minutes, and checked outbound traffic from our container, and I can see it hits the app.launchdarkly.com service to retrieve feature flags with every request. client initialization looks like
$this->client = new LDClient($sdkKey);

and there is nothing in the logs indicating the guzzle middleware package is missing. i even tested the next day in case there was some lag before environment TTL values were updated. i also took a look at what the above post said, and tried creating a new test environment and setting the TTL to a non-zero value when we created it (rather than creating an environment and updating it later down the line. the result was the same). when using the standard PublicCacheStrategy included in the sdk, but with a Flysystem cache storage, i can see the cached value looks something like

O:31:"Kevinrob\GuzzleCache\CacheEntry":8:{s:10:"*request";O:23:"GuzzleHttp\Psr7\Request":7:{s:31:"GuzzleHttp\Psr7\Requestmethod";s:3:"GET";s:38:"GuzzleHttp\Psr7\RequestrequestTarget";N;s:28:"GuzzleHttp\Psr7\Requesturi";O:19:"GuzzleHttp\Psr7\Uri":7:{s:27:"GuzzleHttp\Psr7\Urischeme";s:5:"https";s:29:"GuzzleHttp\Psr7\UriuserInfo";s:0:"";s:25:"GuzzleHttp\Psr7\Urihost";s:20:"app.launchdarkly.com";s:25:"GuzzleHttp\Psr7\Uriport";N;s:25:"GuzzleHttp\Psr7\Uripath";s:25:"/sdk/flags/{MYFLAG}";s:26:"GuzzleHttp\Psr7\Uriquery";s:0:"";s:29:"GuzzleHttp\Psr7\Urifragment";s:0:"";}s:32:"GuzzleHttp\Psr7\Requestheaders";a:4:{s:4:"Host";a:1:{i:0;s:20:"app.launchdarkly.com";}s:13:"Authorization";a:1:{i:0;s:40:"{MYSDKKEY}";}s:12:"Content-Type";a:1:{i:0;s:16:"application/json";}s:10:"User-Agent";a:1:{i:0;s:15:"PHPClient/3.9.1";}}s:36:"GuzzleHttp\Psr7\RequestheaderNames";a:4:{s:4:"host";s:4:"Host";s:13:"authorization";s:13:"Authorization";s:12:"content-type";s:12:"Content-Type";s:10:"user-agent";s:10:"User-Agent";}s:33:"GuzzleHttp\Psr7\Requestprotocol";s:3:"1.1";s:31:"GuzzleHttp\Psr7\Requeststream";O:22:"GuzzleHttp\Psr7\Stream":7:{s:30:"GuzzleHttp\Psr7\Streamstream";i:0;s:28:"GuzzleHttp\Psr7\Streamsize";i:0;s:32:"GuzzleHttp\Psr7\Streamseekable";b:1;s:32:"GuzzleHttp\Psr7\Streamreadable";b:1;s:32:"GuzzleHttp\Psr7\Streamwritable";b:1;s:27:"GuzzleHttp\Psr7\Streamuri";s:10:"php://temp";s:38:"GuzzleHttp\Psr7\StreamcustomMetadata";a:0:{}}}s:11:"*response";O:24:"GuzzleHttp\Psr7\Response":6:{s:38:"GuzzleHttp\Psr7\ResponsereasonPhrase";s:2:"OK";s:36:"GuzzleHttp\Psr7\ResponsestatusCode";i:200;s:33:"GuzzleHttp\Psr7\Responseheaders";a:17:{s:10:"Connection";a:1:{i:0;s:10:"keep-alive";}s:14:"Content-Length";a:1:{i:0;s:3:"397";}s:12:"Content-Type";a:1:{i:0;s:16:"application/json";}s:13:"Cache-Control";a:1:{i:0;s:9:"max-age=0";}s:4:"Etag";a:1:{i:0;s:35:""3caddf4b6448681dba759d4fd8f9075ca"";}s:9:"Ld-Region";a:1:{i:0;s:9:"us-east-1";}s:25:"Strict-Transport-Security";a:1:{i:0;s:16:"max-age=31536000";}s:13:"Accept-Ranges";a:1:{i:0;s:5:"bytes";}s:4:"Date";a:1:{i:0;s:29:"Wed, 29 Jun 2022 17:26:22 GMT";}s:3:"Via";a:1:{i:0;s:11:"1.1 varnish";}s:11:"X-Served-By";a:1:{i:0;s:18:"cache-pao17466-PAO";}s:7:"X-Cache";a:1:{i:0;s:3:"HIT";}s:12:"X-Cache-Hits";a:1:{i:0;s:1:"1";}s:7:"X-Timer";a:1:{i:0;s:26:"S1656523582.207059,VS0,VE1";}s:4:"Vary";a:1:{i:0;s:15:"Accept-Encoding";}s:3:"Age";a:1:{i:0;s:1:"0";}s:16:"X-Kevinrob-Cache";a:1:{i:0;s:4:"MISS";}}s:37:"GuzzleHttp\Psr7\ResponseheaderNames";a:17:{s:10:"connection";s:10:"Connection";s:14:"content-length";s:14:"Content-Length";s:12:"content-type";s:12:"Content-Type";s:13:"cache-control";s:13:"Cache-Control";s:4:"etag";s:4:"Etag";s:9:"ld-region";s:9:"Ld-Region";s:25:"strict-transport-security";s:25:"Strict-Transport-Security";s:13:"accept-ranges";s:13:"Accept-Ranges";s:4:"date";s:4:"Date";s:3:"via";s:3:"Via";s:11:"x-served-by";s:11:"X-Served-By";s:7:"x-cache";s:7:"X-Cache";s:12:"x-cache-hits";s:12:"X-Cache-Hits";s:7:"x-timer";s:7:"X-Timer";s:4:"vary";s:4:"Vary";s:3:"age";s:3:"Age";s:16:"x-kevinrob-cache";s:16:"X-Kevinrob-Cache";}s:34:"GuzzleHttp\Psr7\Responseprotocol";s:3:"1.1";s:32:"GuzzleHttp\Psr7\Responsestream";O:22:"GuzzleHttp\Psr7\Stream":7:{s:30:"GuzzleHttp\Psr7\Streamstream";i:0;s:28:"GuzzleHttp\Psr7\Streamsize";N;s:32:"GuzzleHttp\Psr7\Streamseekable";b:1;s:32:"GuzzleHttp\Psr7\Streamreadable";b:1;s:32:"GuzzleHttp\Psr7\Streamwritable";b:1;s:27:"GuzzleHttp\Psr7\Streamuri";s:10:"php://temp";s:38:"GuzzleHttp\Psr7\StreamcustomMetadata";a:0:{}}}s:15:"*responseBody";s:397:"{"key":"{MYFLAG}","on":false,"prerequisites":[],"targets":[],"rules":[],"fallthrough":{"variation":0},"offVariation":1,"variations":[true,false],"clientSideAvailability":{"usingMobileKey":false,"usingEnvironmentId":false},"clientSide":false,"salt":"{SALT}","trackEvents":false,"trackEventsFallthrough":false,"debugEventsUntilDate":null,"version":58,"deleted":false}";s:10:"*staleAt";O:8:"

after forking the project and changing the GuzzleFeatureRequester to use a GreedyCacheStrategy, our service makes the initial request to get the feature flags, but subsequent requests to app.launchdarkly.com do not exist (as expected). do you have any suggestions? we are considering just forking the project and using the GreedyCacheStrategy.

@eli-darkly
Copy link
Contributor

@dionkimAXS:

We haven't had any other reports of this issue, but the original reporter of this issue seems to have found that it was not actually a problem, so it's hard for me say whether what you're talking about is the same thing. However, similarly to what I discussed with the original reporter, it's unclear to me why you want to use GreedyCacheStrategy with this. What are you trying to accomplish?

@eli-darkly
Copy link
Contributor

It sounds like you are saying that caching currently is not working at all, and that using GreedyCacheStrategy was just one approach you had thought of trying to work around this— is that right?

@eli-darkly
Copy link
Contributor

I'm not able to test against your environment in particular since I don't know your SDK key (please don't post it here! if we do need to do any specific inspection of your environment, then we should move this conversation to a non-public support ticket), but when I test against an environment I created, I see the expected Cache-Control header. Can you tell me what headers you see if you do a request like this:

curl -i -H 'Authorization:YOUR_SDK_KEY' https://sdk.launchdarkly.com/sdk/flags/SOME_FLAG_KEY

@eli-darkly
Copy link
Contributor

Also, it looks like you are using fairly old versions of your dependencies. The SDK has not been tested with Guzzle 6.x, or with guzzle-cache-middleware 1.x (v1.4.0 is over six years old), so it's hard for us to guarantee that those versions will work correctly. Our suggested versions as defined in our composer.json are 7.x and 3.x respectively.

@dionkimAXS
Copy link

yes, the idea is to implement the GreedyCacheStrategy as a means of having some sort of forced caching, since we cannot get it to work properly with the PublicCacheStrategy.

when sending the curl request, there cache-control with max-age is there, so it seems like somethings going wrong elsewhere in the pipeline. unfortunately we cannot use the suggested versions of guzzle and guzzle-cache-middleware, due to our PHP version being pretty old.

i will open a support ticket and continue conversation there. thanks.

@eli-darkly
Copy link
Contributor

OK. Please note that version 3.9.1 of our SDK will become unsupported too, a little over a month from now, per our EOL policy. I'm assuming that the reason you're still using that version is that you require compatibility with PHP 7.2 or lower, and I know sometimes there are obstacles to migrating these things, but we do need to be able to drop support for language versions that are no longer supported by their makers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants