Use case for Feature#remove vs. Feature#disable? #296
I'm using flipper with the ActiveRecord adapter, and I was looking for the ability to disable only the boolean gate (as in #139), but found Feature#disable wipes all the feature's gates from the DB.
What's the intended use case for #remove vs. #disable? I understand #remove deletes the feature record, too, but that record only has a couple of housekeeping fields on it. In my limited testing, the Feature API seems to behave the same whether a feature has no gates or doesn't exist at all. At least for my use case, I think I could use #remove instead of #disable 100% of the time and keep a cleaner DB.
The enable/disable asymmetry with no #disable_boolean threw me for a loop. I'm planning to throw some ugliness in a rake task for this:
# feature.rake namespace :feature do namespace :enable do desc 'undo a system-wide "enable"; restores previously-allowed actors/groups' task :undo, [:feature_name] => :environment do |t, args| args = validate_args(t, args) Flipper::Adapters::ActiveRecord::Gate.where( feature_key: args[:feature_name], key: "boolean" ).delete_all end end end
The text was updated successfully, but these errors were encountered:
Hope that helps! Let me know if you have any other questions.
I'm not sure I follow this. Do you mean you expected that since there is enable/disable there would also be
If you don't mind, I would love to know what you are using flipper for as well and how it is working out for you (what went well, what was hard other than what you mentioned here). If you aren't comfortable leaving that information here in a public comment, feel free to email me directly (it shows up on my profile page). I'm just always curious. :)
Ah, I hadn't considered the web UI. Thanks.
Sorry, I was unclear about asymmetry. I meant how
I'm using flipper for staged feature rollout and masking in-development features on a Rails project at work (with flipper-rails). Enable feature for internal users, enable for a few trusted external users for feedback, enable for the world. We haven't talked about using it for A/B testing yet, but that could come later.
My secret hope is that it lets me merge features in stages with smaller pull requests for easier review and QA without having to expose a half-baked feature to end users.
I'm still at the beginning stages, so I don't have a lot of likes/dislikes yet. The Gates documentation was really helpful for basic usage patterns. I dug around in the REPL to explore the rest of the API.
One issue I had to work around was that double-enabling a feature for an actor or group threw a Postgres exception for violating the
Another was that a feature object's
Yeah this was a tough call early on in the project. Imagine this scenario:
Let's say step 3 sets boolean = false (instead of clearing all the gates). That wouldn't work for Flipper, since flipper checks all gates and the enabled for staff and 25% of actors would remain enabled. What I did originally when I was setting boolean to false is if boolean was false, the result was false no matter what. This solved that issue but created a new one.
Imagine now that we have in addition to the steps above, another one:
What do you expect after step 4? I expect that the feature is enabled for me and me alone. If we leave boolean = false as a short circuit that would mean that any gate enables following the disable (setting boolean = false) would continue to short circuit. So the next thought is let's remove the boolean = false when any future enablements happen like step 4. That creates a new blow expectation though, where the feature is enabled for yourself (single actor), but the previous enablements are also enabled (25% of actors and staff group). Tricky and not expected!
The most clear expectation to me was if you disable, you completely disable and any future enablements will be the only ones for the feature, which is why disable clears instead of setting boolean = false. That is a lot of context, so let me know if I can clear anything up (or if any better ideas come to you which I'm always open to).
Definitely a good idea and a perfect use of flipper.
Interesting, I would have expected that to just ignore/fail silently. I'll add a test case.
Yeah, you can always use strings or symbols, but databases don't have support for symbols so thus key (which is used to store in adapter level) is a string. I find symbols aesthetically more pleasing in code for stuff like this and generally that is all I used. Rarely do I have to use key or the string version.
I expect that the feature remains disabled for everyone, including you. I've been thinking of the boolean gate as a kind of global control. When asking, "is this actor allowed this feature," I've been thinking that it also implies the question, "is this feature enabled for the platform," which is answered by the boolean gate. But my mental model may not match the implementation or intent.
Your expected behavior for step 4 feels like a stack model, which would also work for me. Push group, push percentage, push boolean, push actor. Traverse the stack from top to bottom until you hit a boolean gate (inclusive) or the bottom of the stack. If any of the rules allow access, the flag evaluates to true. Removing the boolean gate would let the logic consider the old rules that were below the gate on the stack. That may be harder for humans to keep track of, though.
Thanks for fixing the double-enable exception!
I was trying to use symbols for everything, too, but found that a feature I created with a symbol name could return a symbol or a string for its