NAME
Toggle - Feature toggles (a.k.a. flippers, flags, switches etc.)
SYNOPSIS
use Redis;
use Toggle;
# This probably happens once for your application, e.g. via Bread::Board
my $redis = Redis->new;
my $toggle = Toggle->new( storage => $redis );
# Define any groups you might need - your sub will be passed the $user
# object that you send to is_active(), and should return true/false.
$toggle->define_group( staff => sub {
my $user = shift;
return $user->has_role('staff');
});
...
# In your controllers
# $user must have an ->id accessor
if ( $toggle->is_active(chat => $user) ) {
# Show this user the shiny new chat feature
}
...
# Elsewhere, in a management UI tool
$toggle->activate_user( chat => $bob ); # Turn it on for Bob
$toggle->activate_group( chat => 'staff' ); # Enable staff testing
$toggle->activate_percentage( chat => 10 ); # 10% rollout
DESCRIPTION
Toggle lets you activate features for different users, storing this configuration in a database like Redis. You can use it to roll out your code to a percentage of users, or specific users/groups that you define.
METHODS
new
Constructor.
my $toggle = Toggle->new( storage => $store );
The storage attribute must be an object that supports get($key)
, set($key, $value)
and del($key)
methods. This happens to be the same interface that Redis uses, but you could make your own.
is_active
Check whether a feature is active. This is the method which you would expect to use all the time in your application code. Can be called in two ways - either to check whether a feature is active for everyone:
$toggle->is_active( 'chat' );
or to check whether it is enabled for a particular user:
$toggle->is_active( chat => $user );
In the second case, the $user object must have an id accessor.
activate
Enable a feature for everyone.
$toggle->activate( 'chat' );
deactivate
Disable a feature for everyone. Useful if you discover a critical bug and want to turn it off altogether. Overrides all the user/group/percentage activations that may have been on previously.
$toggle->deactivate( 'chat' );
define_group
You may wish to use this method to define groups for use below in "activate_group". You pass a subroutine which will accept a single argument (the $user object given to "is_active") and will return a boolean to say whether the user is in the group.
$toggle->define_group( admins => sub { shift->is_an_admin() } );
The group 'all' is defined by default.
$toggle->define_group( all => sub { 1 } );
activate_group
Turn on a feature for a group. The group must have been defined previously (see "define_group"), or be the "all" group.
$toggle->activate_group( chat => 'admins' );
deactivate_group
Turn off a feature for a group. The group must have been defined previously using "define_group".
$toggle->deactivate_group( chat => 'admins' );
Note that any users which have been explicitly enabled via "activate_user" will still be able to see the feature, even if they are in the group.
activate_user
Turn on a feature for an individual user.
$toggle->activate_user( chat => $user );
deactivate_user
Turn off a feature for an individual user.
$toggle->deactivate_user( chat => $user );
activate_percentage
Activate a feature for a percentage of users, such as for an incremental rollout of a new feature.
$toggle->activate_percentage( chat => 10 );
The algorithm used is CRC32( $user->id ) % 100 < percentage
, so as the percentage increases, users do not fall out of the group.
Note that activating the feature for 100% of users will activate the feature globally (i.e. when "is_active" is called without a $user argument).
deactivate_percentage
Deactivate a feature for all users that were receiving an incremental rollout.
$toggle->deactivate_percentage( 'chat' );
Note that users who were previously activated individually or as part of a group will still have the feature active.
features
List all the features that the storage knows about.
my @features = $toggle->features();
add_feature
Add a feature to the storage, but do not activate it for anyone.
$toggle->add_feature( 'chat' );
remove_feature
Remove a feature from the storage.
$toggle->remove_feature( 'chat' );
This will disable it for all users, and will also stop it appearing in the output of "features".
SEE ALSO
Github repo: https://github.com/cv-library/Toggle
Inspired/shamelessly ported from https://github.com/FetLife/rollout
COPYRIGHT
Copyright © 2014 CV-Library Ltd.
Licensed under the same terms as Perl 5.