3 ms·
How do folks implement feature flags? Do most people use feature flags as "remove/add code from/to my application at compile time"? Or do people also use some k
by BossingAround 5y ago
How do folks implement feature flags? Do most people use feature flags as "remove/add code from/to my application at compile time"? Or do people also use some kind of a runtime check system that enables them to toggle functionality while the application is running with some partial reloads or fast restarts?
- t-writescode 5y agoif FEATURE_FLAG_ENABLED(): do_new_version() else: do_old_version() all throughout code. "FEATURE_FLAG_ENABLED()" could be checking a database or an external service. I've also seen it done through environment variables, but I don't like that pattern as much.
- Graffur 5y agoSo for webapps this is in the frontend code and the backend code?
- jason2323 5y agoCurious about this as well
- theshrike79 5y agoMobile app case here: The app fetches its base configuration first from a known URL, before even loading anything except for the most essential parts. This is where we can disable the most basic level of operations or do an emergency shutdown of the client (backend broken or front end exploit found for example) Second level is a version-specific configuration, which can be used to disable all major features of the application. Then there is a system that allows for A-B -testing of features on a client, which can also be used to completely turn off features. It's mostly used to slowly roll out features on the client that might stress the backend in unexpected ways if enabled in one go. The A-B tests are either moved to the second level config feature flags, or permanently turned on or off in a subsequent release.
- yoz 5y agoHi, I'm at LaunchDarkly, a commercial feature flag service. I'll explain how our flags work, which is different from more traditional implementations. But first, as mentioned elsewhere, using a feature flag in code _usually_ looks something like... flagValue = getFlag(FLAG_NAME, user_context) if (flagValue == true) ... do the thing else ... do the other thing So, a couple of those traditional implementations: 1. Environment variables: Good for fast checking; no I/O needed. But if you need to flip a flag, your code won't pick up that change without restarting, maybe even redeploying. Many uses for flags, such as user enablements and kill switches, rely on flag changes being picked up immediately. Plus, this has no targeting capabilities: if a flag is on or off, it's on or off for _everyone_. 2. Request on demand: You store the flags in a database or other external system, then fetch the value when the code evaluates it. This means that flag changes get picked up without restarts, at the cost of blocking I/O. So, the more flags you have, the worse your performance gets. Not great. But if you send the user_context with the flag request, your flag service can do targeting (different flag values for different users) 3. Background polling: Similar to request on demand, except that you keep an in-memory cache so that flag evaluation happens instantly, and that cache is kept up to date with a background thread that periodically checks the flag service. Better performance than request on demand, but updates have more latency. Increasing the poll rate reduces latency at the cost of load on the flag service. Also, the cache will presumably only cache the flag value for the current user, unless you want to build a rule engine which runs locally. Here's how LaunchDarkly does it: Our SDK connects at app startup and downloads the flag data. If it's a server-side SDK, that data will include all the targeting rules. (Yes, we built a rule engine that runs locally. It's pretty powerful.[1]) The SDK caches that data so flags can be evaluated for all user contexts without making a request. However, the SDK then keeps a persistent connection open to our server (or a local proxy). When a flag changes, our server pushes the update through that connection, which updates the SDK's cache instantly. At present, flag updates take about 200ms to propagate to SDKs, usually less. More technical info here: https://docs.launchdarkly.com/sdk/concepts/contributors-guide https://docs.launchdarkly.com/sdk/concepts/contributors-guid... [1] https://docs.launchdarkly.com/sdk/concepts/flag-evaluation-rules https://docs.launchdarkly.com/sdk/concepts/flag-evaluation-r...
- npteljes 5y agoThe most elaborate I've seen IRL is when feature flag management was handled by a service, so they were handled at runtime. The service authenticated the user and then returned a bunch of flags for them. The service also had a web interface for admins to modify the flags; they could be specified on different levels, like system, user, group. The flag service was always called by the backend, so if the frontend needed the flags, the backend forwarded it to them. For a select few flags, the users themselves could toggle them, on a simple interface. The simplest I've done on a small project was just if blocks that checked the username. We had just a few, long term users, and this was used to handle their unique requirements.