-
Notifications
You must be signed in to change notification settings - Fork 213
feat(node): Add experimental FlagDefinitionCacheProvider
#2594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Most packages are already resolving Jest versions from the catalog anyway. This allows better synchronization (node was on Jest 29 but using types for Jest 28).
This interface is used to provide custom caching logic for feature flag definitions used by local eval.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Wiz Scan Summary
To detect these findings earlier in the dev lifecycle, try using Wiz Code VS Code Extension. |
|
Size Change: +6.8 kB (+0.13%) Total Size: 5.06 MB
ℹ️ View Unchanged
|
This exposes experimental types subject to change in minor versions, e.g., FlagDefinitionCacheProvider
ca64f97 to
c4ee36c
Compare
| * @returns true if this instance should fetch, false to skip and read cache | ||
| * @throws if coordination backend is unavailable (error will be logged, fetch continues) | ||
| */ | ||
| shouldFetchFlagDefinitions(): Promise<boolean> | boolean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This initial interface doesn't provide any additional context to the implementation. My justification is that:
- Static information like team id can be provided via the constructor
- We already have configuration for how often we're polling to update cache. If the implementation wants to be smarter about this, they're better off persisting metadata in the cache (such as last fetch time). In a distributed service we can't guarantee things like the last time fetched.
I think there's potentially a case to be made to expose an interface to hit the flag definitions API in the future. For example, it could make HEAD requests and track an ETag or Last-Modified header. Or, maybe that's the context we provide to this method. In any case, we're not quite ready for this and I see this as a future improvement.
| // Important: if `shouldFetchFlagDefinitions` throws, we | ||
| // default to fetching. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this seem reasonable? In the event this method throws (e.g., can't access cache), this would mean all instances resort back to polling directly from the API every interval.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so.
If someone wants different behavior, there's a workaround. They could ensure this never throws (ex: with a wrapper cache provider) and instead make sure it returns false instead.
| /** | ||
| * Experimental APIs | ||
| * | ||
| * This module exports experimental features that may change or be removed in minor versions. | ||
| * Use these APIs with caution and be prepared for breaking changes. | ||
| * | ||
| * @packageDocumentation | ||
| * @experimental | ||
| */ | ||
|
|
||
| export type { FlagDefinitionCacheProvider, FlagDefinitionCacheData } from './extensions/feature-flags/cache' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I marked the interface and config option as @experimental in TSDoc, explaining that it may see breaking changes over minor version bumps. To be really explicit about this, I've also exposed the type under a separate import.
import type { FlagDefinitionCacheProvider } from 'posthog-node/experimental'I'd like to get some real implementations working before we solidify this API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
16 files reviewed, 1 comment
Edit Code Review Agent Settings | Greptile
React with 👍 or 👎 to share your feedback on this new summary format
haacked
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really nice and well thought out.
| * | ||
| * async getFlagDefinitions(): Promise<FlagDefinitionCacheData | undefined> { | ||
| * const cached = await this.redis.get(`posthog:flags:${this.teamKey}`) | ||
| * return cached ? JSON.parse(cached) : undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Folks will copy this. Should we have a try/catch in this example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is fine, if this throws it'll consider it a cache miss. If the data is malformed it's not really recoverable from here anyhow.
| // Important: if `shouldFetchFlagDefinitions` throws, we | ||
| // default to fetching. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so.
If someone wants different behavior, there's a workaround. They could ensure this never throws (ex: with a wrapper cache provider) and instead make sure it returns false instead.
| /** | ||
| * Experimental APIs | ||
| * | ||
| * This module exports experimental features that may change or be removed in minor versions. | ||
| * Use these APIs with caution and be prepared for breaking changes. | ||
| * | ||
| * @packageDocumentation | ||
| * @experimental | ||
| */ | ||
|
|
||
| export type { FlagDefinitionCacheProvider, FlagDefinitionCacheData } from './extensions/feature-flags/cache' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call.
Changes
This change introduces a new
FlagDefinitionCacheProviderinterface. This interface allows custom caching strategies to be implemented for feature flag definitions used by local evaluation.Related to PostHog/posthog#37584
Release info Sub-libraries affected
Libraries affected
Checklist
If releasing new changes
pnpm changesetto generate a changeset file