7 ms·
Feature flags are a nice idea, but nobody outside of Facebook seems to be embracing them. The tooling just isn't there. Some concrete questions: - How do you p
by sillysaurus3 9y ago
Feature flags are a nice idea, but nobody outside of Facebook seems to be embracing them. The tooling just isn't there. Some concrete questions:
- How do you prevent your codebase from becoming if-statement spaghetti?
- How do you prevent new features from being leaked to the user? They'll see the new features in the front end source code. At many companies this isn't an acceptable tradeoff. So do you preprocess the release code and strip out the disabled feature flags? With what?
- What do you use to control feature flags? Just a json file filled with `"foo-bar-feature": true/false`, or something more sophisticated like a control panel that you can use to say "10% of our users will see this feature"?
- NicoJuicy 9y agoWho says no one is embracing them? There are tons of tools available if you check for it. But you should google for "feature toggle" libraries and not feature flags
- mabbo 9y ago> How do you prevent your codebase from becoming if-statement spaghetti? A valid point- if you're not careful that can happen. Key things: remove those ifs after a launch, and launch fully or remove the feature; consider 'hiding' the ifs behind factories that build the objects that implement the different logic; also, if you have 20 features is development for the same area of your codebase, worry- you may be trying too much! > How do you prevent new features from being leaked to the user? I haven't had to worry about this very often just based on my projects, but there are strategies. You could be sending the user a different version of the js/html based on the feature flags (preprocessor as you said). Haven't had to do that, but woah that would be a fun little project. > What do you use to control feature flags? My favorite implementation was an S3 json file that effectively encoded a decision tree based on variables used. In code, we could say "here are the five variables about this request, feature object are you enabled?". By modifying that json file, you could change the features state at run time. (Note: this was not perfectly implemented/designed by me and caused a few issues when we first used it. Oops. But you can do very quick solutions too, read a file or make an object that decides based on non-dynamic logic.
- jasode 9y ago>A valid point- if you're not careful that can happen. Key things: remove those ifs after a launch I think a big factor that's unspoken about "trunk-based-master" development is that it fits better with "website apps" such as Facebook and Etsy. The "live website" can be thought of as a "single executable" and trunk-based mental model maps well to that. The feature-flags as a replacement for branches doesn't result in an unusable combinatorial explosion. There are minimal # of "alternate universes" of Facebook... maybe a "Facebook for internal engineers" etc. You can tame that with feature-flags. However, for corporate development where the output is "exe" files... e.g. version 2.x of product has dependencies on a old version of a library and a version 3.x uses a totally different architecture with different conflicting dependencies... you can't model that code evolution in a clean manner with feature-flag "if" statements. If you move the "if" statements outside of the code and into preprocessors (#ifdef) or the "build" system such as cmake, you've just shifted the problem around instead of solving it. Branches instead of feature-flags are cleaner and more sane for certain domains.
- mabbo 9y agoFortunately, exe development is becoming a small subset of software these days.
- hoorayimhelping 9y ago>Feature flags are a nice idea, but nobody outside of Facebook seems to be embracing them I worked at Etsy from early 2012 to late 2015 and I used feature flags every day I was there. >How do you prevent your codebase from becoming if-statement spaghetti? You remove the feature flag checking code when you turn off or turn on the feature. It's an extra deploy, but it needs to be part of the prod/eng process. This is the most salient issue of feature flagging in my experience and something you need to get ahead of from the get-go. >How do you prevent new features from being leaked to the user? You branch at the server/request level, not the client level, so there is no set of features that gets displayed, it's just what the server returns. >What do you use to control feature flags? You can use a service like LaunchDarkly or Optimizely or you can write your own service, or you can have a file in memory. Usually it starts simple with boolean toggles and evolves into a ramp up system that let's you selectively target users. The important part is that you need to be able to change features without redeploying code.
- sillysaurus3 9y agoYou remove the feature flag checking code when you turn off or turn on the feature. It's an extra deploy, but it needs to be part of the prod/eng process. This is the most salient issue of feature flagging in my experience and something you need to get ahead of from the get-go. I don't understand. I was asking about the development source code, not the code delivered to the user. The dev source code isn't stripped of if-statements, right? That's where the feature flag toggling lives. But then it seems like it's easy to devolve into spaghetti. You branch at the server/request level, not the client level, so there is no set of features that gets displayed, it's just what the server returns. Ok, but how? I'm not playing dumb. Assume an express server. You want to put a feature flag into your codebase. What is step #1 (and #2 and ... #N) to achieve this? I looked up LaunchDarkly. $299/mo for basic team support. Uhh... That's almost the cost of WeWork office space. Are feature flags really so nascent that there isn't a FOSS solution for it?
- hoorayimhelping 9y agoThe expectation of a bunch of weird branches making everything confusing (I had that too) ends up being unfounded. You typically only see a few places with branching logic, and people usually draw attention to it being branching logic for a feature or experiment. How and where you branch really depends on the feature. If you're A/B testing a button color, you'll deploy a different strategy than if you're trying to introduce new logic with minimal regressions. But you can plan out your strategy in both cases to minimize leaking information and disrupting user experience (and you should). >Ok, but how? I'm not playing dumb. Assume an express server. You want to put a feature flag into your codebase. What is step #1 (and #2 and ... #N) to achieve this? The general flow is: get status of features from source of truth. Check current feature flag's status. Do something based on that status. You can make it as complicated or simple as you like. You can have a global boolean flag for all features where it's always either true or false. You can have different flags for different users, you can have certain percentages of users have different values for flags. But it all starts from getting the value of a flag for this current request from the source of truth. Let's say you're writing a crud app on an express server that communicates via http to a database service. Your database service is rolling out v5 of their api, and they're at the last stages of their beta so they're pretty confident. You decide you want to test it by routing half of all the traffic to your crud app through v5 and the other half as normal through v4. You could lay out your code in several ways, and you'll have to figure out what works best for your model and your team. Let's assume you have a feature service you query on every request (maybe it's express middleware) to see if an experiment is enabled for the current user, and you've queried your current user against api v5, and you have a boolean variable indicating whether to show v5 or v4 and it's used in a route handler for your home route. You could change the url you hit based on the state of the experiment, provided the interface to the api is the same. const routeUrl = '/api/v4/home/' if (featureIsEnabled) { routeUrl = '/api/v5/home/' } Inside the route home route handler you could have an if/case statement that did a completely different request and response. if (featureIsEnabled) { return queryV5('home').then(respondToV5).catch(handleV5); } else { return queryV4('home').then(respondToV4).catch(handleV4); } You can also do this on the front end - a lot of feature / experiment services have front-end libraries. I prefer to do it server side.
- QuercusMax 9y agoThere's used a ton at Google, except they're called "experiments". I believe that term comes from A/B testing, which they're still heavily used for, but they're also used for feature rollouts.
- hyperpallium 9y agoDependency injection? The conditionals are then virtual (which implementation of an interface); the same controls apply to front-end code; global dependency configuration.Though all that infrastructure and boilerplate for explicit modularity is probably only worthwhile at Facebook-scale. With each feature in a separate file, there is no merging of features, and if you squint your eyes you can see each possible dependency configuration as a git branch, selecting certain files out of a repository, just at runtime. There are no file-level merges, only different files, and different configuration selections. (Of course, modifying code to use the interface in the first place is a file-level change.) BTW I've been thinking about this problem in the context of computational fluid dynamics, where you want to try different scales, fluid and container initial condition profiles and boundary conditions, as well as different discretizations, schemes and variations thereof. Basically, experimental cases (a bit like "functional test" setups).
- latencyloser 9y agoThe project I work on at Microsoft uses feature flags. I see it with many Azure services as well. I can testify that it is absolutely if-statement hell, at least in the areas that rely on these feature flags. However, I will say I think 'lazy programming' is more the issue than the flags themselves. For example, isolating feature specific behavior to it's own impl and using an abstract class to share common behavior--that sort of basic stuff gets skipped in favor of 'time'. Thankfully these are all obscured from the user for the most part. We have a 'control panel' like thing that we used to enable/disable feature switches. It works well for its use case and let's us enable/disable with as much granularity as we want.
- kostarelo 9y agoCan you give us some examples of those feature flags?
- latencyloser 9y agoHmm. I can't get into detail. But we use it for things that are mostly 'experimental' for the customer. Let's take the all-to-common TODO MVC app and say I add a caching layer between the app and the database. I would likely add a feature flag to enable or disable retrieving or storing results in the new caching layer. Or, I add a new button that lets the customer multi-select TODO tasks, that would have a feature switch, etc. The reason for this is that it lets us enable these features for customers who either insist on having them or are excited to try new features without exposing the entire customer base to the risk of these features. The big problem with this is: you end up having 'if(feature)' type statements _everywhere_ for each of those experimental buttons or extra components or whatever. It creates considerable debt that the team has to be accountable for cleaning up as those features start to stabilize.
- dahart 9y ago> Feature flags are a nice idea, but nobody outside of Facebook seems to be embracing them. The tooling just isn't there. This might be just a terminology problem. Any company that does A/B testing is using feature flags, so pretty much most of the web is using them. I'd bet more or less all programmers have them in their repos too, maybe you just call them something else, or didn't think they could be called feature flags. If you have a config file, chances are high that you have feature flags already. For tooling, I get the feeling you're thinking of feature flags as something other than your config files and code constants. But that's it: feature flags are really simple. Add a boolean const defaulted to false in your config somewhere, and wrap the code in an if statement. When you need to A/B test or release incrementally, that's when you need extra non-trivial code around features, and that's often not something someone else can provide. Turning the feature on and off requires specific knowledge of your project's stack and UI.
- guelo 9y agoI've used feature flags at 3 non-facebook companies.
- kccqzy 9y agoI think there are many different equally valid ways to use feature flags. We use feature flags to slowly ramp up the release of new features only. We have per-user feature flag settings too. We have a small team so the number of new features that need to be gradually released is very small, and won’t make the codebase a mess of `if` statements. We don’t really worry about feature flags leaking to users because when we start to use the feature flag, there is already a group of users being able to use the feature (usually employees because of dogfooding, and then gradually to a selected group of power users/VIPs). The frontend JS code is already minified beyond recognition (we use Google Closure compiler in advanced mode) so that’s not really a concern. Since feature flags are per-user, you can think of them as a column of the users table in the database.
- kcorbitt 9y agoAt Google every significant feature in our codebase was behind a feature flag. Pro is that you can roll out features slowly and do a statistical analysis of their impact on user behavior in a well-controlled way. Also, you can turn off a broken feature really fast without having to wait for a new deploy (especially important with native mobile apps). The big downside was that it significantly impacted developer velocity. You have to test that everything still works with/without your feature enabled. Also, sometimes supporting the old and new way of doing things simultaneously requires a nasty hack, and when you go back in to pull out the old code after a successful deploy you don't actually bother to rearchitect things the way you ought to. For Google they were probably inevitable, but for a small to mid-sized company I would avoid them.
- baylisscg 9y agoFeature flags _are_ widely used. They generally manifest as commented out code. Like many features that migrate down from these massive codebases it's a common behaviour thats been systematised.
- krzyk 9y agoI've worked at Sabre some time ago and we used feature flags intensively. Feature was enabled/disabled using our own configuration server (which was used to configure many other things) - it was basically a dynamic file with booleans, that we could turn on/off. After the feature was released we removed the if statement from the code.