Do not belittle rake tasks

45617fd77f12f016894c0931771b2a98?s=47 mbie
November 06, 2018

Do not belittle rake tasks



November 06, 2018


  1. Do Not Belittle Rake Tasks Mateusz Bielec RRUG #16, 06.11.2018

  2. What is a rake task? • Just a script to

    run at any time in a console • Common Rails tasks: ◦ rake db:reset, rake db:create, rake db:migrate ◦ rake -T ◦ rake routes • Custom task: desc 'Rake task description' task :name_of_task do # Your code goes here end
  3. When we use custom rake tasks? • Script automation •

    Data cleanup • Long database migration
  4. Why is it important to write a good custom rake

    task? • Usually it’s production code • Readability • Maintainability • Testing • Transparency
  5. pg

  6. My list of the things to consider • Size of

    .rake file • Idempotency • Tracking progress • Logging the work • Isolated structure • Testing • The performance
  7. * without the boilerplate

  8. Ideal .rake file namespace :mailchimp desc 'Import users from Mailchimp'

    task import_users: :environment do end end
  9. Keep .rake file as small as possible namespace :mailchimp desc

    'Import users from Mailchimp' task :import_users do puts 'Importing users from Mailchimp' result = puts "Successfully imported #{result} users!" end end

  11. Idempotency • It’s important on cleanups and migrations • Can

    be easily fulfilled with: ◦ a good query ◦ modifying the input file ◦ omitting already created data

  13. Tracking progress • The task executor needs to know the

    current status of the task • Show anything ◦ from dots ◦ to printing a line for each processed item • Or use a gem ProgressBar:
  14. ProgressBar gem namespace :cleanup desc 'Cleanup bad fees' task :fix_bad_fees

    do query = progress_bar = ProgressBar.create( title: 'Fixing bad fees by adding a discount', total: query.count ) # ... end end namespace :cleanup desc 'Cleanup bad fees' task :fix_bad_fees do # ... result = query) do progress_bar.increment end puts "Successfully fixed #{result} fees!" end end
  15. ProgressBar gem class Cleanup::FixBadFees::Task def*args, &block) new.self(*args, &block) end

    def call(query:) query.find_each do # Fix bad fees yield if block_given? end end end

  17. Logging • Who performed the task? When? Why? • Log

    the action ◦ Notes ◦ Audit trail ◦ History events • Log the task’s execution • Include the executor ◦ TASK_EXECUTOR=jon.snow@westeros rake kill_undead

  19. Isolated structure • .rake files usually in /lib/tasks • The

    rest in /app/tasks • Each task in a separated module

  21. Testing custom rake tasks • Automated tests class for each

    PORO class used in a rake task • No automated tests for .rake file, rely on manual testing • Don’t be lazy

  23. Performance • Predict the scale at the very beginning •

    Define bottlenecks ◦ Reading from large file or from multiple database tables ◦ Calling external services ◦ Saving many rows to the database • Use database close to production (locally, staging)
  24. Summary • Rake task are a part of our application

    • Bad task may cause a lot of damage • With a little of effort we can do it right