49 karma · joined February 27, 2014
One thing I'm curious about is Sleuth's approach to the "garbage in, garbage out" problem-- if I'm tracking (e.g.) MTTR, I've found that our teams aren't always perfect about tracking the start / end times of an incident. If the data's incorrect, can I modify it in manually?
We then use a streaming API to serve rule changes, so when you make a change to your dashboard, the new rules are streamed to all your backend servers within a few hundred milliseconds.
If you need even more resiliency, you can deploy a small service in your own infrastructure (https://github.com/launchdarkly/ld-relay) that allows you to persist these flag configurations in Redis.
The last remaining piece is our core data, and there's no strong push to move it out of Mongo.
Events are stored in DynamoDB. We use mongo for "core" data like accounts, feature flags, etc, but none of the high throughput stuff touches MongoDB.
We eagerly create "cleanup branches" and corresponding pull requests to remove a flag-- that front-loads the cleanup work and means we aren't context switching back to try and remember how to clean up a flag.
Also, we've found that in practice flags are usually independent-- testing permutations of flags shouldn't typically be necessary. People usually take an analogous shortcut with feature branches-- we test branches in isolation but don't usually re-test after merging.
And of course, we'll launch new features behind a flag. I'll admit that we've had two or three occasions where we had to hit the kill switch after a deploy, so I'm rather glad we had a LaunchDarkly for our LaunchDarkly.
[edit] here's a shot of our dogfood instance: https://twitter.com/jkodumal/status/717786744750477312
re: conditionals, DI: our SDKs focus on the base technique (flags based on conditionals), but it's possible to wrap that core with higher-level approaches like DI, etc. We're considering going down that path, but where it makes sense to do so, and not have to re-implement higher-level wrappers for every framework out there. So, e.g.-- in Ruby, I can see us providing higher-level APIs specific to Rails.
Dependent feature flags are also an interesting problem-- we don't have a solution to that yet, but we do spend a lot of time thinking about feature flags, and I hope we'll have something on that front soon :)
We have more coming, including an ability to mark "permanent" flags that should never be removed.
The product is built API-first-- everything in our UI is driven via our own REST API. Docs are here: http://apidocs.launchdarkly.com/
By default, the SDKs use server-sent events to push feature flags to an in-memory store. If you need persistence + strong consistency, you can back the SDK with Redis as well.
Disclaimer: I'm one of the co-founders of LaunchDarkly.
For the most part, flags are independent. When I first started using DVCS (back in the Bitkeeper days) we all thought that merge conflicts from doing feature branching would be a headache, but this didn't end up being the case. I've found the same with feature flags. While it's possible for flags to interact poorly, or to introduce "dependent" or nested flags, it hasn't been a problem for us in practice.
This seems to scale, too-- I haven't heard this to be an issue in practice at larger orgs (Etsy, Netflix, etc.) that do feature flag-driven development.
We manage the cleanup issue by defining a "removal branch" that cleans up the feature flag at the same time the feature flag is introduced. This sticks around as a dormant pull request during the lifetime of the flag. It's not much overhead when this is done early. Cleanup does become painful when the code's not fresh in your mind.
Note that we do feature branches as well as feature flags-- trunk vs. branch based development is orthogonal to using feature flags.
But the real power behind the idea is not the ifdef piece, it's the idea of dynamic, context-aware configuration. You've got a user-friendly tool that can control the code paths being executed in your application without restarts or redeploys.