Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 187 lines (119 sloc) 6.349 kb
de91a5f @jnunemaker Bundle gem files
authored
1 # Flipper
8257cc6 @jnunemaker Initial commit
authored
2
491afa8 @jnunemaker Readme updates.
authored
3 Feature flipping is the act of enabling or disabling features or parts of your application, ideally without re-deploying or changing anything in your code base.
4
5 The goal of this gem is to make turning features on or off so easy that everyone does it. Whatever your data store, throughput, or experience, feature flipping should be easy and relatively no extra burden to your application.
6
9e3565f @jnunemaker Readme note about production use
authored
7 ## Note
8
9 This project is a work in progress and not ready for production yet, but will be very soon.
10
491afa8 @jnunemaker Readme updates.
authored
11 ## Why not use <insert gem name here, most likely rollout>?
12
13 I've used rollout extensively in the past and it was fantastic. The main reason I reinvented the wheel to some extent is:
14
15 * API - For whatever reason, I could never remember the API for rollout.
16 * Adapter Based - Rather than force redis, if you can implement a few simple methods, you can use the data store of your choice to power your flippers (memory, file system, mongo, redis, sql, etc.). It is also dead simple to front your data store with memcache if you so desire since feature checking is read heavy, as opposed to write heavy.
17
18 ## Coming Soon™
19
20 * Web UI (think resque UI for features toggling/status)
21 * Optimizations for per request in process caching of trips to the adapter
a6f744d @jnunemaker Example in readme.
authored
22
23 ## Usage
24
491afa8 @jnunemaker Readme updates.
authored
25 The goal of the API for flipper was to have everything revolve around features and what ways they can be enabled. Start with top level and dig into a feature, then dig in further and enable that feature for a given type of access, as opposed to thinking about how the feature will be accessed first (ie: stats.enable vs activate_group(:stats, ...)).
26
02a0b7a @jnunemaker Readme formatting
authored
27 ```ruby
c0d59b6 @jnunemaker Update readme to new dsl and add types
authored
28 require 'flipper'
15d7808 @jnunemaker Correct readme.
authored
29 require 'flipper/adapters/memory'
02a0b7a @jnunemaker Readme formatting
authored
30
c0d59b6 @jnunemaker Update readme to new dsl and add types
authored
31 # pick an adapter
32ea402 @jnunemaker Hash not needed
authored
32 adapter = Flipper::Adapters::Memory.new
02a0b7a @jnunemaker Readme formatting
authored
33
c0d59b6 @jnunemaker Update readme to new dsl and add types
authored
34 # get a handy dsl instance
35 flipper = Flipper.new(adapter)
36
37 # grab a feature
38 search = flipper[:search]
39
491afa8 @jnunemaker Readme updates.
authored
40 # check if that feature is enabled
41 if search.enabled?
42 puts 'Search away!'
43 else
44 puts 'No search for you!'
02a0b7a @jnunemaker Readme formatting
authored
45 end
46
47 puts 'Enabling Search...'
48 search.enable
491afa8 @jnunemaker Readme updates.
authored
49
50 # check if that feature is enabled again
51 if search.enabled?
52 puts 'Search away!'
53 else
54 puts 'No search for you!'
55 end
02a0b7a @jnunemaker Readme formatting
authored
56 ```
de91a5f @jnunemaker Bundle gem files
authored
57
c0d59b6 @jnunemaker Update readme to new dsl and add types
authored
58 Of course there are more [examples for you to peruse](https://github.com/jnunemaker/flipper/tree/master/examples).
59
60 ## Types
61
491afa8 @jnunemaker Readme updates.
authored
62 Out of the box several types of enabling are supported. They are checked in this order.
63
64 ### 1. Boolean
65
66 All on or all off. Think top level things like :stats, :search, :logging, etc. Also, an easy way to release a new feature as once a feature is boolean enabled it is on for every situation.
67
68 ```ruby
69 flipper = Flipper.new(adapter)
70 flipper[:stats].enable # turn on
71 flipper[:stats].disable # turn off
72 flipper[:stats].enabled? # check
73 ```
74
75 ### 2. Group
76
77 Turn on feature based on value of block. Super flexible way to turn on a feature for multiple things (users, people, accounts, etc.)
78
79 ```ruby
80 Flipper.register(:admins) do |actor|
81 actor.respond_to?(:admin?) && actor.admin?
82 end
83
84 flipper = Flipper.new(adapter)
85 flipper[:stats].enable flipper.group(:admins) # turn on for admins
86 flipper[:stats].disable flipper.group(:admins) # turn off for admins
87 person = Person.find(params[:id])
88 flipper[:stats].enabled? person # check if enabled, returns true if person.admin? is true
89 ```
90
91 There is no requirement that the thing yielded to the block be a user model or whatever. It can be anything you want therefore it is a good idea to check that the thing passed into the group block actually responds to what you are trying.
92
93 ### 3. Individual Actor
94
95 Turn on for individual thing. Think enable feature for someone to test or for a buddy.
96
97 ```ruby
98 flipper = Flipper.new(adapter)
99
100 # convert user or person or whatever to flipper actor for storing and checking
101 actor = flipper.actor(user.id)
102
103 flipper[:stats].enable actor
104 flipper[:stats].enabled? actor # true
105
106 flipper[:stats].disable actor
107 flipper[:stats].disabled? actor # true
108 ```
109
110 ### 4. Percentage of Actors
111
112 Turn this on for a percentage of actors (think users or people). Consistently on or off for this user as long as percentage increases. Think slow rollout of a new feature to users.
113
114 ```ruby
115 flipper = Flipper.new(adapter)
116
117 # convert user or person or whatever to flipper actor for checking if in percentage
118 actor = flipper.actor(user.id)
119
120 # returns a percentage of actors instance set to 10
121 percentage = flipper.actors(10)
122
123 # turn stats on for 10 percent of users in the system
124 flipper[:stats].enable percentage
125
126 # checks if actor's identifier is in the enabled percentage
127 flipper[:stats].enabled? actor
128
129 ```
130
131 ### 5. Percentage of Random
132
133 Turn this on for a random percentage of time. Think load testing new features behind the scenes and such.
134
135 ```ruby
136 flipper = Flipper.new(adapter)
137
138 # get percentage of random instance set to 5
139 percentage = flipper.random(5)
140
141 # turn on logging for 5 percent of the time randomly
142 # could be on during one request and off the next
143 # could even be on first time in request and off second time
144 flipper[:logging].enable percentage
145 ```
146
147 Randomness is probably not a good idea for enabling new features in the UI. Most of the time you want a feature on or off for a user, but there are definitely times when I have found percentage of random to be very useful.
148
149
150 ## Adapters
151
152 I plan on supporting in-memory, Mongo, and Redis as adapters for flipper. Others are welcome so please let me know if you create one.
153
154 ### Memory
155
156 You can use this for tests if you want. That is pretty much all I use it for.
157
158 ### Mongo
159
160 Currently, the mongo adapter stores everything in a single document. This is cool as if you cache that document for the life of a web request or whatever, you can check a ton of features by adding very little burden (1 query per request).
161
162 ### Redis
c0d59b6 @jnunemaker Update readme to new dsl and add types
authored
163
491afa8 @jnunemaker Readme updates.
authored
164 Redis is great for this type of stuff and it only took a few minutes to implement. The only real problem with redis right now is that automated failover isn't that easy so relying on it for every code path in my app would make me nervous.
c0d59b6 @jnunemaker Update readme to new dsl and add types
authored
165
de91a5f @jnunemaker Bundle gem files
authored
166 ## Installation
167
168 Add this line to your application's Gemfile:
169
170 gem 'flipper'
171
172 And then execute:
173
174 $ bundle
175
a6f744d @jnunemaker Example in readme.
authored
176 Or install it yourself with:
de91a5f @jnunemaker Bundle gem files
authored
177
178 $ gem install flipper
179
180 ## Contributing
181
182 1. Fork it
183 2. Create your feature branch (`git checkout -b my-new-feature`)
184 3. Commit your changes (`git commit -am 'Added some feature'`)
185 4. Push to the branch (`git push origin my-new-feature`)
186 5. Create new Pull Request
Something went wrong with that request. Please try again.