Feature Flipping

🐬

Cosaaaa?

  • Modificare comportamenti di un'app senza cambiare codice
  • Se non ci credete: https://martinfowler.com/articles/feature-toggles.html

Casi d'uso

  • Rilascio Graduale
  • Test performance
  • Test fattibilità (websocket in production)
  • Feature solo per alcuni utenti (utenti in USA oppure Admin)
  • Feature attive in alcuni momenti (Black Friday)

Pro

  • Si può disabilitare una feature immediatamente se qualcosa non va, tornando alla vecchia versione senza deploy.
  • Si può deployare una feature immediatamente, non deve essere perfetta, tanto è disabilitata. Questo consente di studiare gli effetti della feature prima di pubblicarla. PR piccole = 🥳
  • Si può degradare il sistema in caso di un picco di visite, per esempio togliendo delle parti della UI carine ma non indispensabili che hanno un grande impatto sulle performance

Contro

  • complexity: aggiungere if = 💩
  • test: si devono testare entrambi gli scenari, aggiungendo context
  • refactor: una volta rilasciata si deve rimuovere il vecchio codice, si potrebbe prevedere un deprecation warning?

Implementazioni

(Nel mondo Ruby/Rails)

gem "ruby_flipper"

  • molto leggera
  • ~200 LOC (calcolate ad occhio)
  • fornisce solo una DSL
  • le logiche di flipping vanno implementate via codice
# Gemfile
gem 'ruby_flipper'


# config/features.rb
feature :new_header, Figaro.env.new_header

feature :redwood_checkout do |params, session|
  percentage_of_traffic = Figaro.env.redwood_checkout_traffic_percentage.to_i

  session[:checkout_version] = case
    when params[:redwood] == 'true'
      'redwood'
    when params[:redwood] == 'false'
      'control'
    when session[:checkout_version]
      session[:checkout_version]
    when (rand(100) < percentage_of_traffic)
      'redwood'
    else
      'control'
    end

  next session[:checkout_version] == 'redwood'
end

# any application file
if feature_active?(:new_header)
  #.. do magic things
end
  • No UI
  • serve un deploy per flipping
  • vecchia e poche stars
  • le logiche vanno implementate via codice

gem "flipper"

  • mantenuta e molte stars
  • Web UI
  • Soluzione completa: adapters, gates, api, etc.
gem 'flipper'
gem 'flipper-redis'
gem 'flipper-ui'

# config/features.rb
Flipper.configure do |config|
  config.default do
    client = Redis.new
    adapter = Flipper::Adapters::Redis.new(client)
    flipper = Flipper.new(adapter)
  end
end

# config/routes.rb
YourRailsApp::Application.routes.draw do
  mount Flipper::UI.app(Flipper) => '/flipper'
end

# any application file
if Flipper.enabled?(:search)
  puts 'Search away!'
else
  puts 'No search for you!'
end
  • Pesantina
  • Web UI (nelle mani degli admin)

Flipper Web UI

Quale scegliamo?

Quale scegliamo?

Made with Slides.com