Skip to content

Instantly share code, notes, and snippets.

@tsnow
Last active August 29, 2015 13:57
Show Gist options
  • Save tsnow/9416351 to your computer and use it in GitHub Desktop.
Save tsnow/9416351 to your computer and use it in GitHub Desktop.
For the love of god stop talking about feature toggles and build a usable system

[11:50 AM] Ryan Naughton: hola

so you did the original work on adding rollout and the features class wrapper for it

in discussing our various feature flag capabilities, I realized our current solutions weren't very uniform or adequate (mainly the provider_feature_bitmasks and the system_configs)

and I needed to add fleet level feature flags that werent related to any booking channel

so I added this:

  •   https://github.com/ridecharge/rc/pull/575
    

it has since started a discussion on (a) naming conventions since I called my model Feature and yours is Features and (b) whether it is necessary since we have rollout

my thoughts are that rollout is great but for a lot of features, we will want them persisted in the DB

and part of the db refresh so we can ensure we have the right features set in different environments for easily reproducibility and testing

I was wondering if you could look at that PR and give your thoughts

another aspect of what I was building is I can imagine expanding it

it uses polymorphic associations to allow any feature flag to be set on any activerecord object

an expansion I am thinking of is let's say we want to have ride specific feature flags

we could create a service object or method that checks the permissions of the user and permissions of the fleet to create permissions for a new ride on the fly

so with this system we could create derived permissions/enabled/disabled features from AR associations

##[12:34 PM] Tim Snowhite:

There was a little discussion of this already, just to give you some context:

  •   https://github.com/ridecharge/rc/pull/557#issuecomment-36377935 
    
  •   https://github.com/ridecharge/rc/pull/557#issuecomment-36391217 
    
  •   https://github.com/ridecharge/rc/pull/542#issuecomment-35905468 
    
  •   https://gist.github.com/tsnow/9182426#file-z_provider_features-rb 
    
  •   https://github.com/ridecharge/rc/pull/557
    

That said, I feel very remiss at this point for not building a UI for interacting with the Features user-based rollout implementation. I think not having a UI caused a lot of confusion.

If you'd like, feel free to rename the Features class to UserFeatures or something like that, it's not connected to a db table (it uses redis) so it should be a pretty simple rename.

(That said, I find the ability to turn a feature on for all the employees at TM a really helpful thing, and it'd be nice if we could keep that part of the rollout gem's feature set.)

Lastly, I don't really care how many tables or data stores we use to represent the feature toggles.

I think it would help if:

    1. the code had a single interface for checking and setting feature flags (see the ProviderFeatures discussion stuff, yours also covers this.)
    1. that it's not necessary to have console access to flip the toggles. (So that QA, Mobile, and Ops can flip the toggles when it benefits them. I failed on this one with the Features class.)

Whatever you guys decide, though.

[12:49 PM] Tim Snowhite:

Basically, I like what you've done, but what you've got should be the internals of a separate interface. 

You've built at the equivalent level of the rollout gem, a general system for feature toggles untied to the domain it will be embedded in, now there's extra stuff that should go on top which makes it useful in our domain.

[1:24 PM] Tim Snowhite:

Two quick points:

  •    1) There are at least three workflows of toggles in the system:
    

One, which Features and VersionedContext are both taking part in, is things we're trying to roll out globally, but just haven't yet, for various reasons.

Methods like https://github.com/ridecharge/rc/blob/38e13ce0400b7a1d2d2ef4d6badfdb67dda9beb5/app/models/features.rb#L20-L22 provide a place to 'return true' when we decide we want these to be fully rolled out to all users.

Then there are per-fleet configuration settings. These don't follow any defined progression, they stay toggled for very long periods, and are dependent on external systems and businesses. They're really a record of external system configuration.

Finally, There are cut-off switches for external service boundaries. https://github.com/ridecharge/rc/blob/38e13ce0400b7a1d2d2ef4d6badfdb67dda9beb5/app/models/features.rb#L17-L19 is an example of one of these. https://github.com/ridecharge/rc/blob/38e13ce0400b7a1d2d2ef4d6badfdb67dda9beb5/app/controllers/services/internal_service_controller.rb#L27 is another.

  •   2) "and part of the db refresh so we can ensure we have the right features set in different environments for easily reproducibility and testing"
    

I believe much of this, from a mobile booking perspective, could probably be done in a more visible way by using per-user feature toggles, along with a UI to see the status for your user, and flip the toggles. E.g. things like zero_auth can be done on a per-user basis without issue.

That said, these things later tend to become per-fleet configuration settings, so the feature toggle interface could check multiple data stores / objects for a particular toggle.

that last point is kinda pie-in-the-sky, sorry.

Trying to get away from shared state across testers in the testing environments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment