1,346 karma · joined February 5, 2013
For the temporary type of toggle, which is what I was addressing with this blog post, my experience coincides with yours-- usually a few weeks.
The trick with deleting a year-old flag (which I was trying to address with this post) was that you need to be careful when deleting code that you haven't worked on in over a year. If you have the list of necessary changes all pre-baked in a branch, this can be at least a little easier.
I'm not aware of any authorization libraries that let you grant access to a percentage of your users, but maybe they are out there? It is a strange use case from an 'authorization' standpoint.
The point is not to make flag cleanup automatic. It is to front-load the work of cleaning it up when the complexities involved are fresh in your mind. That way, when it comes time to clean it up, it is much easier to be more confident that you found all of the edge cases.
-master---------------*--------------------*--
\-feature-branch---/ /
\-cleanup-branch-----/The point is not to delete the flag promptly, the point is to delete it cleanly, when you are confident the new feature is good.
Keep in mind that Google hasn't been a superpower for very long. All of this 'no one can ever disrupt Google' talk is nonsense.
If you are going to make a schema migration with no downtime (even if you are not feature-flagging it) you will need to make the code work with both the old and new schema for a period, anyway. So, if you are feature flagging it, this period might just be extended, and you roll out the migration slowly. The 'new' thing I introduce with this approach is really just the 'integrity check' (and the gradual rollout, allowing you to monitor for errors/performance issues).
For example, if your migration involves:
- adding/removing a field: your code needs to deal with the fact that the field might not be there. This usually means you have a reasonable default value, or something.
- restructuring: this is a broad category, so lets work with a more concrete example: you currently have a nested (unbounded) repeating sub-object, and you want to break them out into their own top-level documents in another table/collection. In this case, you will have a DAO function `getChildren(parent)`, which uses the feature flag to decide if it should make the query to read the parent, and then pull out the nested list of children, or if it should load the children from their separate collection. You can save the children in both places, and do the dual reads as well, comparing the results. When the cutover is complete, you run a script that removes the nested children (instead of decommissioning the old database, like in the example in the blog post).
Ultimately, the concept is the same: you do the work in both places for a period of time, and check the results. If there are any discrepancies, you still have the fully-functional original data source.
In this way, the Dynamo data was kind of throw-away, until we were confident in everything.
Yeah, at that point, you are doing two writes, and (possibly) two reads. I simplified the code a bit for the blog post, but you can do the read and write pairs concurrently, so you don't have to wait longer to get data to return to the caller.
You can also provide a default value that will be used if the network is not available. You can read from a config file to drive this if you need to, to allow devs to specify the flag value when offline. This is what we do for our dogfood environment (prod, staging, and dev environments all talk to dogfood, but dogfood doesn't have another LaunchDarkly to talk to).
Hope that helps!
[1]: http://docs.launchdarkly.com/
nb: I'm an engineer at LaunchDarkly
[1] https://en.wikipedia.org/wiki/Confessions_of_an_Economic_Hit...
But if you are tunneling an HTTP service, you can be assigned a random hostname (random.ngrok.com), or you can request a specific hostname (pkaeding-test.ngrok.com), and your service will be available over both HTTP (port 80) and HTTPS (port 443) on that hostname. This can be critical for testing webhook callbacks where the remote service only allows HTTPS on port 443.
Also, when you are tunneling HTTP services (using HTTP or HTTPS), ngrok will start a web UI running at localhost:3030, detailing all incoming requests. You can examine the headers and body from both request and response, and even replay requests. This is immensely helpful when debugging webhooks.
(I am not affiliated with ngrok, except as a happy user.)
At least, that has been my experience, though I may make more of an effort than most to use fresh ingredients rather than canned/prepared foods (based on the slow cooker recipes online, which seem to disproportionately call for canned ingredients).
That said, I love the output of the slow cooker, and I agree it is a great tool to have. It helps to mix things up and have a different meal this week than last week.
It was a fun project, and hopefully people (continue) to find it useful!