rollout-redis ⛳️
Fast and easy feature flags based on Redis.
Based on the discontinued rollout project, removing some capabilities, including some new features and supporting latest Redis versions.
Topics covered in this README:
- Install it
- Quick Start
- Advanced features
- Rake tasks
- Migrating from rollout gem
- Changelog
- Contributing
Install it
gem install rollout-redis
Quick Start 💨
Instantiate the Rollout
class sending a Redis
instance as a parameter.
require 'redis'
require 'rollout'
@redis ||= Redis.new(
host: ENV.fetch('REDIS_HOST'),
port: ENV.fetch('REDIS_PORT')
)
@rollout ||= Rollout.new(@redis)
Now you can activate Feature Flags:
@rollout.activate('FEATURE_FLAG_NAME') # => true/false
Verify if a feature is currently enabled:
if @rollout.active?('FEATURE_FLAG_NAME')
# your new code here...
end
An alternative to the if check, is to wrap your code under the with_feature
method. The wrapped code will be performed only if the feature flag is active:
@rollout.with_feature('FEATURE_FLAG_NAME') do
# your new code here...
end
If there is an issue, you have the option to disable a feature:
@rollout.deactivate('FEATURE_FLAG_NAME')
If you want to list all the stored feature flags, you can use the features
method:
@rollout.features
The response will be an array of hashes with all the information about the stored feature flags
[
{ name: 'a-feature-flag', percentage: 100, data: { requests: 50, errors: 1 } },
{ name: 'another-feature-flag', percentage: 20, data: { requests: 1, errors: 0 } },
{ name: 'super-feature-flag', percentage: 50, data: { requests: 828, errors: 34 } }
]
Advanced features 🦾
Gradual activation based on percentages
When introducing a new feature, it's a recommended practice to gradually enable it for a specific portion of your target audience to evaluate its impact. To achieve this, you can utilize the activate
method, as shown below:
@rollout.activate('FEATURE_FLAG_NAME', 20)
Now, to know if a feature flags is enabled, you need to provide a determinator (in this example, we're using the user email):
if @rollout.active?('FEATURE_FLAG_NAME', user_email)
# your new code here...
end
The gradual activation also works wrapping your code within the with_feature
method, you just need to provde the determinator you want to use.
@rollout.with_feature('FEATURE_FLAG_NAME', user_email) do
# your new code here...
end
It's important to note that if you use the active?
method without specifying a determinator to determine whether this subset of the audience should see the new feature, it will always return false
since the activation percentage is less than 100%. See:
@rollout.activate('FEATURE_FLAG_NAME', 20)
@rollout.active?('FEATURE_FLAG_NAME') # => false
Caching Feature Flags
The Rollout gem is tightly integrated with Redis for feature flag status management. Consequently, occasional connectivity issues between your application and the Redis storage may arise.
To prevent potential application degradation when the Redis storage is unavailable, you can enable feature flag status caching during the gem's instantiation:
@rollout ||= Rollout.new(redis).with_cache
Additionally, you can specify extra parameters to configure the duration (in seconds) for which the feature flag status is stored in the cache. By default, this duration is set to 300 seconds (5 minutes):
@rollout ||= Rollout.new(redis)
.with_cache(expires_in: 300)
In the case that you need to clear the cache at any point, you can make use of the clean_cache
method:
@rollout.clean_cache
Auto-deactivating flags
If you want to allow the gem to deactivate your feature flag automatically when a threshold of erros is reached, you can enable the degrade feature using the with_degrade
method.
@rollout ||= Rollout.new(redis)
.with_cache
.with_degrade(sample: 5000, min: 100, threshold: 0.1)
So now, instead of using the active?
method, you need to wrap your new code under the with_feature
method.
@rollout.with_feature('FEATURE_FLAG_NAME') do
# your new feature code here...
end
When any unexpected error appears during the wrapped code execution, the Rollout gem will take it into account for automatically deactivating the feature flag if the threshold of errors is reached. All the managed or captured errors inside the wrapped code will not be taken into consideration.
Rake tasks
In order to have access to the rollout rakes, you have to load manually the task definitions. For doing so load the rollout rake task:
require 'rollout'
load 'rollout/tasks/rollout.rake'
Usage
To activate/deactivate features, execute the following rake tasks:
bundle exec rake rollout:on[feature_name]
bundle exec rake rollout:off[feature_name]
To a gradual activation based on percentages, pass the percentage as the second parameter when executing the on
task.
bundle exec rake rollout:on[feature_name,50]
NOTE: In both cases, feature_name
must not include quotes e.g. bundle exec rake rollout:on['feature_name']
, as the gem will be unable to fetch its activation status if so.
For listing all the stored feature flags, do:
bundle exec rake rollout:list
Migrating from rollout gem 🚨
If you are currently using the unmaintained rollout gem, you should consider checking this migration guide for start using the new rollout-redis
gem.
Changelog
If you're interested in seeing the changes and bug fixes between each version of rollout-redis
, read the Changelog.
Contributing
We welcome and appreciate contributions from the open-source community. Before you get started, please take a moment to review the guidelines below.
How to Contribute
- Fork the repository.
- Clone the repository to your local machine.
- Create a new branch for your contribution.
- Make your changes and ensure they meet project standards.
- Commit your changes with clear messages.
- Push your branch to your GitHub repository.
- Open a pull request in our repository.
- Participate in code review and address feedback.
- Once approved, your changes will be merged.
Development
This project is dockerized. Once you clone the repository, you can use the Make
commands to build the project.
make build
You can pass the tests running:
make test
Issue Tracker
Open issues on the GitHub issue tracker with clear information.
Contributors
- Juan Carlos García - Creator - https://github.com/jcagarcia
The rollout-redis
gem is based on the discontinued rollout project, created by James Golick