Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache bundle list and rake -P #216

Open
schneems opened this issue Oct 6, 2023 · 0 comments
Open

Cache bundle list and rake -P #216

schneems opened this issue Oct 6, 2023 · 0 comments

Comments

@schneems
Copy link
Contributor

schneems commented Oct 6, 2023

Deploying with a cached CNB is fast. Really fast. But it could be faster. Right now it takes about 6 seconds (below). I think we could make it faster if we skip running bundle exec rake -P (1.5~3 seconds) and bundle list (~0.3s). Here's an example output, and below I'll explain the logic that I think allows us to safely skip these:

# Heroku Ruby Buildpack

- Metrics agent
  - Skipping install (`gem 'barnes'` not found in Gemfile.lock)
- Ruby version `3.1.3` from `Gemfile.lock`
  - Using cached version
- Bundler version `2.4.7` from `Gemfile.lock`
  - Using cached version
- Bundle install
  - Loading cache
  - Skipping `bundle install` (no changes found in /workspace/Gemfile, /workspace/Gemfile.lock, or user configured environment variables)
  - ! HELP To force run `bundle install` set `HEROKU_SKIP_BUNDLE_DIGEST=1`
- Setting default processes(es)
  - Running `bundle list` ... (0.313s)
  - Detected rails app (`rails` gem)
- Rake assets install
  - Rake detected (`rake` gem found, `Rakefile` found ad `/workspace/Rakefile`)
  - Running `bundle exec rake -P --trace` ...... (3.038s)
  - Compiling assets with cache (detected `rake assets:precompile` and `rake assets:clean` via `bundle exec rake -P`)
  - Loading cache for /workspace/public/assets
  - Loading cache for /workspace/tmp/cache/assets
  - Running `bundle exec rake assets:precompile assets:clean --trace`

      ** Invoke assets:precompile (first_time)
      ** Invoke assets:environment (first_time)
      ** Execute assets:environment
      ** Invoke environment (first_time)
      ** Execute environment
      ** Execute assets:precompile
      ** Invoke assets:clean (first_time)
      ** Invoke assets:environment
      ** Execute assets:clean

  - Done (2.030s)
  - Storing cache for /workspace/public/assets
  - Storing cache for /workspace/tmp/cache/assets
- Done (finished in 6.188s)

Skipping Bundle list

If the bundle install step is skipped, we can use the same metadata to skip the bundle list step, and use the same HEROKU_SKIP_BUNDLE_DIGEST to force this to run.

Skipping rake -P

This is trickier as someone could delete all the code in their Rakefile and we wouldn't catch it without this task. I think my logic looks like this:

  • If both assets:precompile and assets:clean are found in the last run (store in the metadata) then assume both of them continue to exist and run the tasks without first running rake -P
    • PASS: Do nothing, continue on with the program execution, we guessed correctly
    • FAIL: Re-run the rake -P check.
      • If those tasks did exist then we already ran them and they failed, so fail the build
      • If those tasks no longer exist, then move forward accordingly
        • Has assets:precompile without assets:clean - Re run just assets:precompile, update the cache so it will eagerly check on next deploy and continue the build as normal
        • Does not have assets:precompile or assets:clean update the cache so it will eagerly check on next deploy and continue the build as normal

This is essentially a try-catch strategy. I believe for the most common case (tasks existed last deploy and still exist today) that this is a decent strategy.

We need some kind of way to turn it off. Possibly HEROKU_SKIP_RAKE_TASK_CACHE=1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant