switches¶ ↑
Switches lets you turn on and off sections of your code with Switches.foobar?
booleans.
It’s an extraction from brighterplanet.com, where we use it as an emergency button to turn on/off API integration with Facebook, Campaign Monitor, etc.
Quick start¶ ↑
Add 2 lines to config/environment.rb
:
require File.join(File.dirname(__FILE__), 'boot') [...] require 'switches' # AFTER boot, BEFORE initializer [...] Rails::Initializer.run do |config| [...] config.gem 'switches', :lib => false # INSIDE initializer
Now run this:
my-macbook:~/my_app $ ./script/runner 'Switches.setup'
Add your defaults to config/switches/defaults.yml
:
--- ssl: true # ssl support is on by default campaign_monitor: true # campaign monitor integration is on by default
Tasks¶ ↑
RAKE TASK CAP TASK NOTES rake s:c cap TARGET s:c show current switches rake s:d cap TARGET s:d show difference between current and default switches rake s:on[SWITCH] cap TARGET s:on ARG=SWITCH turn on SWITCH rake s:off[SWITCH] cap TARGET s:off ARG=SWITCH turn off SWITCH rake s:clear[SWITCH] cap TARGET s:clear ARG=SWITCH clear any switch for SWITCH rake s:reset cap TARGET s:reset go back to defaults (deletes config/switches/current.yml) rake s:backup cap TARGET s:backup backup current switches (copies to config/switches/backup.yml) rake s:restore cap TARGET s:restore restore backed-up switches (copies backup.yml to current.yml) rake s:default cap TARGET s:default list default settings
Throwing switches remotely with Capistrano¶ ↑
This is the minimum needed in the TARGET task:
task :production do role :app, 'ec2-88-77-66-55.compute-1.amazonaws.com' role :app, '177.133.33.144' set :rails_env, 'production' set :deploy_to, '/data/my_app' set :gfs, false end
The switches will get applied to any role that matches /app/
(so :app_master, :app, etc.)
Throwing switches before you db:migrate¶ ↑
I like to use Switches to turn off %w{memoization caching facebook campaign_monitor delayed_job}
before running rake db:migrate, so I put this in lib/tasks/zzz_rake_switches.rake
:
namespace :rake_switches do task :turn_stuff_off do Rake::Task['s:backup'].execute %w{memoization caching facebook campaign_monitor delayed_job}.each do |switch| Rake::Task['s:off'].execute(Rake::TaskArguments.new([:name], [switch])) end end task :turn_stuff_back_on do Rake::Task['s:restore'].execute Rake::Task['cache:clear'].execute end end # modify what happens on db:migrate, etc. [ 'db:migrate', 'your:task:if:it:needs:wrapping' ].each do |task_to_wrap| Rake::Task[task_to_wrap].enhance(['rake_switches:turn_stuff_off']) do Rake::Task['rake_switches:turn_stuff_back_on'].invoke end end
Note that ‘s:backup’ and ‘s:restore’ are not thread safe or really GFS safe, either.
Usage¶ ↑
You can do stuff like (in app/models/user.rb
):
after_create :subscribe_email if Switches.campaign_monitor? def subscribe_email CampaignMonitor.subscribe email end
Uhh ohh! Campaign Monitor’s API is down and you need to shut off those failing after_creates, like, NOW.
production-server-1:/var/www/apps/my_app $ rake s:off[campaign_monitor] production-server-1:/var/www/apps/my_app $ sudo monit restart all -g my_app [...] production-server-2:/var/www/apps/my_app $ rake s:off[campaign_monitor] production-server-2:/var/www/apps/my_app $ sudo monit restart all -g my_app
Or, even better, do it with cap:
my-macbook:~/my_app $ cap production s:off ARG=campaign_monitor my-macbook:~/my_app $ cap production mongrel:restart
For another example, let’s say you’re a developer who doesn’t have a self-signed certificate:
my-macbook:~/my_app $ rake s:off[ssl]
Those changes get persisted in config/switches/current.yml
.
If you want to see your switches vis-a-vis the defaults:
my-macbook:~/my_app $ rake s:d --- ssl: true => false
And if you want to go back to the defaults:
my-macbook:~/my_app $ rake s:reset
Remember, you should version control config/switches/defaults.yml
and ignore config/switches/current.yml
.
Rationale¶ ↑
Sometimes you just need an easy way to “turn off” code.
Wishlist¶ ↑
+ ?
Copyright¶ ↑
Copyright © 2009 Seamus Abshere. See LICENSE for details.