Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Refactoring with Science

Refactoring with Science

Using data and Science to refactor with greater confidence.

Wynn Netherland

February 21, 2014
Tweet

More Decks by Wynn Netherland

Other Decks in Programming

Transcript

  1. Write lots of TESTS. ! ❯ testrb test/integration/api/repos_test.rb Loading suite

    in dotcom mode ... Run options: # Running tests: Finished tests in 30.638101s, 4.7979 tests/s, 64.7886 assertions/s. 147 tests, 1985 assertions, 0 failures, 0 errors, 0 skips ruby -v: ruby 2.1.0p0-github (development) [x86_64-darwin13.0]
  2. !

  3. !

  4. 2009 ! # General configuration settings, required for all recipes!

    set :application, "project-name" set :domain, "project-domain" set :extra_domains, %w() # Add something like www.project-domain.com role :app, domain role :web, domain role :db, domain, :primary => true ! # set :user, "user" ! # Deployment Settings set :repository, "repository url" set :deploy_to, "/absolute/path/to/location/your/server" set :deploy_via, :checkout set :config_files, %w() ! # SSH Keys for caching (you must generate these first.) ssh_options[:keys] = %w(~/.ssh/mykey1 ~/.ssh/mykey2) ! # Change this to :thin if you want to use Thin instead. set :app_server, :mongrel ! # Change this to :merb if you want to use Merb instead. (experimental) set :app_framework, :rails ! # ============================================================= # Application Server Settings (Thin or Mongrel) # ============================================================= set :app_servers, 1 set :app_server_port, 7007 set :app_environment, 'production' set :app_server_address, '127.0.0.1' set :app_server_conf, "#{shared_path}/config/thin.yml" ! # ============================================================= # Nginx Settings
  5. !

  6. ! %

  7. !

  8. ! The following deployments are based on actual events. Branch

    names and SHAs have been changed to protect the innocent.
  9. ! hubot where can I deploy? > Environments for github

    ----------------------------------------------------- production: unlocked lab-one: locked 6 hours ago by jasonrudolph lab-two: unlocked sekret-lab: unlocked playground: unlocked
  10. ! hubot deploy github/api-my-feature to production > Merge master into

    api-my-feature for pengwynn - hubot github/github@deadbeef
  11. !

  12. ! hubot deploy github/api-my-feature to production > pengwynn is deploying

    github/api-my-feature (beefdead..deadbeef) to production pengwynn's production deployment of github is NOW )))! (22s)
  13. !

  14. !

  15. !

  16. !

  17. !

  18. ! > pengwynn: it looks like you merged "api-my-feature" branch

    into master, so I've unlocked production.
  19. ! > pengwynn is deploying github/master to production pengwynn is

    deploying github/master to lab-one pengwynn is deploying github/master to lab-two pengwynn is deploying github/master to sekret-lab
  20. ! 1

  21. !

  22. !

  23. require "dat/science" ! class MyApp::Widget def allows?(user) experiment = Dat::Science::Experiment.new

    \ "widget-permissions" do |e| ! e.control { old_method } # old way e.candidate { new_method } # new way end ! experiment.run end end
  24. require "dat/science" ! class MyApp::Widget def allows?(user) experiment = Dat::Science::Experiment.new

    \ "widget-permissions" do |e| ! e.control { old_method } # old way e.candidate { new_method } # new way end ! experiment.run end end
  25. require "dat/science" ! class MyApp::Widget def allows?(user) experiment = Dat::Science::Experiment.new

    \ "widget-permissions" do |e| ! e.control { old_method } # old way e.candidate { new_method } # new way end ! experiment.run end end
  26. require "dat/science" ! class MyApp::Widget def allows?(user) experiment = Dat::Science::Experiment.new

    \ "widget-permissions" do |e| ! e.control { old_method } # old way e.candidate { new_method } # new way end ! experiment.run end end
  27. require "dat/science" ! class MyApp::Widget def allows?(user) experiment = Dat::Science::Experiment.new

    \ "widget-permissions" do |e| ! e.control { old_method } # old way e.candidate { new_method } # new way end ! experiment.run end end
  28. require "dat/science" ! class MyApp::Widget def allows?(user) experiment = Dat::Science::Experiment.new

    \ "widget-permissions" do |e| ! e.control { old_method } # old way e.candidate { new_method } # new way end ! experiment.run end end
  29. require "dat/science" ! class MyApp::Widget def allows?(user) science "widget-permissions" do

    |e| e.control { model.check_user(user).valid? } e.candidate { user.can? :read, model } end end end
  30. require "dat/science" ! class MyApp::Widget def allows?(user) science "widget-permissions" do

    |e| e.control { model.check_user(user).valid? } e.candidate { user.can? :read, model } end end end
  31. require "dat/science" ! class Blog::Post def permalink(user) science "permalink" do

    |e| e.control { post[:permalink] } e.candidate { post.slug } e.comparator {|a, b| a.downcase == b.downcase } end end end
  32. require "dat/science" ! class Blog::Post def permalink(user) science "permalink" do

    |e| e.control { post[:permalink] } e.candidate { post.slug } e.comparator {|a, b| a.downcase == b.downcase } end end end
  33. require "dat/science" ! module Myapp class Experiment < Dat::Science::Experiment def

    enabled? rand(100) < 10 # Run 10% of the time end end end
  34. require "dat/science" ! module Myapp class Experiment < Dat::Science::Experiment def

    publish MyApp.instrument "science.#{event}", payload end end end
  35. require "dat/science" ! module Myapp class Experiment < Dat::Science::Experiment def

    publish MyApp.instrument "science.#{event}", payload end end end
  36. require "dat/science" ! class Blog::Post def permalink(user) science "permalink" do

    |e| e.context :post => post e.control { post[:permalink] } e.candidate { post.slug } e.comparator {|a, b| a.downcase == b.downcase } end end end
  37. require "dat/science" ! class Blog::Post def permalink(user) science "permalink" do

    |e| e.context :post => post e.control { post[:permalink] } e.candidate { post.slug } e.comparator {|a, b| a.downcase == b.downcase } end end end
  38. module GitHub class Experiment < Dat::Science::Experiment class << self #

    Public: enable mad science mode: returns the candidate values by default # instead of the control. def mad_science=(val) @mad_science = val end ! # Internal: whether or not to always run the candidate instead of the # control. def candidate_instead_of_control? @mad_science end end … end
  39. module GitHub class Experiment < Dat::Science::Experiment class << self #

    Public: enable mad science mode: returns the candidate values by default # instead of the control. def mad_science=(val) @mad_science = val end ! # Internal: whether or not to always run the candidate instead of the # control. def candidate_instead_of_control? @mad_science end end … end