bootsnap 1.4.5 → 1.18.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +264 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +63 -23
  5. data/exe/bootsnap +5 -0
  6. data/ext/bootsnap/bootsnap.c +504 -184
  7. data/ext/bootsnap/extconf.rb +30 -15
  8. data/lib/bootsnap/bundler.rb +3 -1
  9. data/lib/bootsnap/cli/worker_pool.rb +136 -0
  10. data/lib/bootsnap/cli.rb +283 -0
  11. data/lib/bootsnap/compile_cache/iseq.rb +72 -21
  12. data/lib/bootsnap/compile_cache/json.rb +89 -0
  13. data/lib/bootsnap/compile_cache/yaml.rb +316 -41
  14. data/lib/bootsnap/compile_cache.rb +27 -17
  15. data/lib/bootsnap/explicit_require.rb +5 -3
  16. data/lib/bootsnap/load_path_cache/cache.rb +73 -37
  17. data/lib/bootsnap/load_path_cache/change_observer.rb +25 -3
  18. data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +27 -82
  19. data/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +2 -0
  20. data/lib/bootsnap/load_path_cache/loaded_features_index.rb +63 -29
  21. data/lib/bootsnap/load_path_cache/path.rb +42 -19
  22. data/lib/bootsnap/load_path_cache/path_scanner.rb +60 -29
  23. data/lib/bootsnap/load_path_cache/store.rb +64 -23
  24. data/lib/bootsnap/load_path_cache.rb +40 -38
  25. data/lib/bootsnap/setup.rb +3 -36
  26. data/lib/bootsnap/version.rb +3 -1
  27. data/lib/bootsnap.rb +141 -36
  28. metadata +15 -99
  29. data/.github/CODEOWNERS +0 -2
  30. data/.github/probots.yml +0 -2
  31. data/.gitignore +0 -17
  32. data/.rubocop.yml +0 -20
  33. data/.travis.yml +0 -21
  34. data/CODE_OF_CONDUCT.md +0 -74
  35. data/CONTRIBUTING.md +0 -21
  36. data/Gemfile +0 -8
  37. data/README.jp.md +0 -231
  38. data/Rakefile +0 -12
  39. data/bin/ci +0 -10
  40. data/bin/console +0 -14
  41. data/bin/setup +0 -8
  42. data/bin/test-minimal-support +0 -7
  43. data/bin/testunit +0 -8
  44. data/bootsnap.gemspec +0 -45
  45. data/dev.yml +0 -10
  46. data/lib/bootsnap/load_path_cache/core_ext/active_support.rb +0 -106
  47. data/lib/bootsnap/load_path_cache/realpath_cache.rb +0 -32
  48. data/shipit.rubygems.yml +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be54a60d54f32f824d5c2fdccf189cdcb5409d1848c55f6e654fe44ace1d3f21
4
- data.tar.gz: c6239c30984a936b76e218c2b1292a7e72d817d3e4847a6c58f0121c1e3068dc
3
+ metadata.gz: 4fa4ab785277ee01a1c8ee75b43f0efb93db42bffcdacc1c8505a65efa03dede
4
+ data.tar.gz: 8aaaca48ae257b563580023c8fa36a59463f4c30f5463c14f6b8b94bf5fe27df
5
5
  SHA512:
6
- metadata.gz: c251990457406cd51726eec8d62e0e1028bbeade6e24f266cb743d6f00f53650841beed9ee8e1795c78febd18ea234691125920c16aa5a95031718a28619bb31
7
- data.tar.gz: 554a885bf2264f088618c41864fb84069d0664b35af0ae4b619c8fbb1cf285c80fad564d36845161f8044c35c6b53a33e66f27eb75c6715f25869af2795c97f6
6
+ metadata.gz: 27b48d27d3330c8565952a2fbb979e71013b1e9585bcb3284656192808c304f2874c32a135b14895eec61a7ef038fa71fa111964a56e7aaedc9ff507ef307686
7
+ data.tar.gz: c3d83a0b068f2908a6298c7cd8e1a660f1228a7ddbfb9409cb3f6c174319f3974388ce73756c04062b17b97a37e199a07bccbb0b8dc1c6224998c58c51194b27
data/CHANGELOG.md CHANGED
@@ -1,3 +1,267 @@
1
+ # Unreleased
2
+
3
+ # 1.18.3
4
+
5
+ * Fix the cache corruption issue in the revalidation feature. See #474.
6
+ The cache revalidation feature remains opt-in for now, until it is more battle tested.
7
+
8
+ # 1.18.2
9
+
10
+ * Disable stale cache entries revalidation by default as it seems to cause cache corruption issues. See #471 and #474.
11
+ Will be re-enabled in a future version once the root cause is identified.
12
+ * Fix a potential compilation issue on some systems. See #470.
13
+
14
+ # 1.18.1
15
+
16
+ * Handle `EPERM` errors when opening files with `O_NOATIME`.
17
+
18
+ # 1.18.0
19
+
20
+ * `Bootsnap.instrumentation` now receive `:hit` events.
21
+ * Add `Bootsnap.log_stats!` to print hit rate statistics on process exit. Can also be enabled with `BOOTSNAP_STATS=1`.
22
+ * Revalidate stale cache entries by digesting the source content.
23
+ This should significantly improve performance in environments where `mtime` isn't preserved (e.g. CI systems doing a git clone, etc).
24
+ See #468.
25
+ * Open source files and cache entries with `O_NOATIME` when available to reduce disk accesses. See #469.
26
+ * `bootsnap precompile --gemfile` now look for `.rb` files in the whole gem and not just the `lib/` directory. See #466.
27
+
28
+ # 1.17.1
29
+
30
+ * Fix a compatibility issue with the `prism` library that ships with Ruby 3.3. See #463.
31
+ * Improved the `Kernel#require` decorator to not cause a method redefinition warning. See #461.
32
+
33
+ # 1.17.0
34
+
35
+ * Ensure `$LOAD_PATH.dup` is Ractor shareable to fix an conflict with `did_you_mean`.
36
+ * Allow to ignore directories using absolute paths.
37
+ * Support YAML and JSON CompileCache on TruffleRuby.
38
+ * Support LoadPathCache on TruffleRuby.
39
+
40
+ # 1.16.0
41
+
42
+ * Use `RbConfig::CONFIG["rubylibdir"]` instead of `RbConfig::CONFIG["libdir"]` to check for stdlib files. See #431.
43
+ * Fix the cached version of `YAML.load_file` being slightly more permissive than the default `Psych` one. See #434.
44
+ `Date` and `Time` values are now properly rejected, as well as aliases.
45
+ If this causes a regression in your application, it is recommended to load *trusted* YAML files with `YAML.unsafe_load_file`.
46
+
47
+ # 1.15.0
48
+
49
+ * Add a readonly mode, for environments in which the updated cache wouldn't be persisted. See #428 and #423.
50
+
51
+ # 1.14.0
52
+
53
+ * Require Ruby 2.6.
54
+ * Add a way to skip directories during load path scanning.
55
+ If you have large non-ruby directories in the middle of your load path, it can severely slow down scanning.
56
+ Typically this is a problem with `node_modules`. See #277.
57
+ * Fix `Bootsnap.unload_cache!`, it simply wouldn't work at all because of a merge mistake. See #421.
58
+
59
+ # 1.13.0
60
+
61
+ * Stop decorating `Kernel.load`. This used to be very useful in development because the Rails "classic" autoloader
62
+ was using `Kernel.load` in dev and `Kernel.require` in production. But Zeitwerk is now the default, and it doesn't
63
+ use `Kernel.load` at all.
64
+
65
+ People still using the classic autoloader might want to stick to `bootsnap 1.12`.
66
+
67
+ * Add `Bootsnap.unload_cache!`. Applications can call it at the end of their boot sequence when they know
68
+ no more code will be loaded to reclaim a bit of memory.
69
+
70
+ # 1.12.0
71
+
72
+ * `bootsnap precompile` CLI will now also precompile `Rakefile` and `.rake` files.
73
+
74
+ * Stop decorating `Module#autoload` as it was only useful for supporting Ruby 2.2 and older.
75
+
76
+ * Remove `uname` and other platform specific version from the cache keys. `RUBY_PLATFORM + RUBY_REVISION` should be
77
+ enough to ensure bytecode compatibility. This should improve caching for alpine based setups. See #409.
78
+
79
+ # 1.11.1
80
+
81
+ * Fix the `can't modify frozen Hash` error on load path cache mutation. See #411.
82
+
83
+ # 1.11.0
84
+
85
+ * Drop dependency on `fileutils`.
86
+
87
+ * Better respect `Kernel#require` duck typing. While it almost never comes up in practice, `Kernel#require`
88
+ follow a fairly intricate duck-typing protocol on its argument implemented as `rb_get_path(VALUE)` in MRI.
89
+ So when applicable we bind `rb_get_path` and use it for improved compatibility. See #396 and #406.
90
+
91
+ * Get rid of the `Kernel.require_relative` decorator by resolving `$LOAD_PATH` members to their real path.
92
+ This way we handle symlinks in `$LOAD_PATH` much more efficiently. See #402 for the detailed explanation.
93
+
94
+ * Drop support for Ruby 2.3 (to allow getting rid of the `Kernel.require_relative` decorator).
95
+
96
+ # 1.10.3
97
+
98
+ * Fix Regexp and Date type support in YAML compile cache. (#400)
99
+
100
+ * Improve the YAML compile cache to support `UTF-8` symbols. (#398, #399)
101
+ [The default `MessagePack` symbol serializer assumes all symbols are ASCII](https://github.com/msgpack/msgpack-ruby/pull/211),
102
+ because of this, non-ASCII compatible symbol would be restored with `ASCII_8BIT` encoding (AKA `BINARY`).
103
+ Bootsnap now properly cache them in `UTF-8`.
104
+
105
+ Note that the above only apply for actual YAML symbols (e..g `--- :foo`).
106
+ The issue is still present for string keys parsed with `YAML.load_file(..., symbolize_names: true)`, that is a bug
107
+ in `msgpack` that will hopefully be solved soon, see: https://github.com/msgpack/msgpack-ruby/pull/246
108
+
109
+ * Entirely disable the YAML compile cache if `Encoding.default_internal` is set to an encoding not supported by `msgpack`. (#398)
110
+ `Psych` coerce strings to `Encoding.default_internal`, but `MessagePack` doesn't. So in this scenario we can't provide
111
+ YAML caching at all without returning the strings in the wrong encoding.
112
+ This never came up in practice but might as well be safe.
113
+
114
+ # 1.10.2
115
+
116
+ * Reduce the `Kernel.require` extra stack frames some more. Now bootsnap should only add one extra frame per `require` call.
117
+
118
+ * Better check `freeze` option support in JSON compile cache.
119
+ Previously `JSON.load_file(..., freeze: true)` would be cached even when the msgpack version is missing support for it.
120
+
121
+ # 1.10.1
122
+
123
+ * Fix `Kernel#autoload`'s fallback path always being executed.
124
+
125
+ * Consider `unlink` failing with `ENOENT` as a success.
126
+
127
+ # 1.10.0
128
+
129
+ * Delay requiring `FileUtils`. (#285)
130
+ `FileUtils` can be installed as a gem, so it's best to wait for bundler to have setup the load path before requiring it.
131
+
132
+ * Improve support of Psych 4. (#392)
133
+ Since `1.8.0`, `YAML.load_file` was no longer cached when Psych 4 was used. This is because `load_file` loads
134
+ in safe mode by default, so the Bootsnap cache could defeat that safety.
135
+ Now when precompiling YAML files, Bootsnap first try to parse them in safe mode, and if it can't fallback to unsafe mode,
136
+ and the cache contains a flag that records whether it was generated in safe mode or not.
137
+ `YAML.unsafe_load_file` will use safe caches just fine, but `YAML.load_file` will fallback to uncached YAML parsing
138
+ if the cache was generated using unsafe parsing.
139
+
140
+ * Minimize the Kernel.require extra stack frames. (#393)
141
+ This should reduce the noise generated by bootsnap on `LoadError`.
142
+
143
+ # 1.9.4
144
+
145
+ * Ignore absolute paths in the loaded feature index. (#385)
146
+ This fixes a compatibility issue with Zeitwerk when Zeitwerk is loaded before bootsnap. It also should
147
+ reduce the memory usage and improve load performance of Zeitwerk managed files.
148
+
149
+ * Automatically invalidate the load path cache whenever the Ruby version change. (#387)
150
+ This is to avoid issues in case the same installation path is re-used for subsequent ruby patch releases.
151
+
152
+ # 1.9.3
153
+
154
+ * Only disable the compile cache for source files impacted by [Ruby 3.0.3 [Bug 18250]](https://bugs.ruby-lang.org/issues/18250).
155
+ This should keep the performance loss to a minimum.
156
+
157
+ # 1.9.2
158
+
159
+ * Disable compile cache if [Ruby 3.0.3's ISeq cache bug](https://bugs.ruby-lang.org/issues/18250) is detected.
160
+ AKA `iseq.rb:13 to_binary: wrong argument type false (expected Symbol)`
161
+ * Fix `Kernel.load` behavior: before `load 'a'` would load `a.rb` (and other tried extensions) and wouldn't load `a` unless `development_mode: true`, now only `a` would be loaded and files with extensions wouldn't be.
162
+
163
+ # 1.9.1
164
+
165
+ * Removed a forgotten debug statement in JSON precompilation.
166
+
167
+ # 1.9.0
168
+
169
+ * Added a compilation cache for `JSON.load_file`. (#370)
170
+
171
+ # 1.8.1
172
+
173
+ * Fixed support for older Psych. (#369)
174
+
175
+ # 1.8.0
176
+
177
+ * Improve support for Psych 4. (#368)
178
+
179
+ # 1.7.7
180
+
181
+ * Fix `require_relative` in evaled code on latest ruby 3.1.0-dev. (#366)
182
+
183
+ # 1.7.6
184
+
185
+ * Fix reliance on `set` to be required.
186
+ * Fix `Encoding::UndefinedConversionError` error for Rails applications when precompiling cache. (#364)
187
+
188
+ # 1.7.5
189
+
190
+ * Handle a regression of Ruby 2.7.3 causing Bootsnap to call the deprecated `untaint` method. (#360)
191
+ * Gracefully handle read-only file system as well as other errors preventing to persist the load path cache. (#358)
192
+
193
+ # 1.7.4
194
+
195
+ * Stop raising errors when encountering various file system errors. The cache is now best effort,
196
+ if somehow it can't be saved, bootsnap will gracefully fallback to the original operation (e.g. `Kernel.require`).
197
+ (#353, #177, #262)
198
+
199
+ # 1.7.3
200
+
201
+ * Disable YAML precompilation when encountering YAML tags. (#351)
202
+
203
+ # 1.7.2
204
+
205
+ * Fix compatibility with msgpack < 1. (#349)
206
+
207
+ # 1.7.1
208
+
209
+ * Warn Ruby 2.5 users if they turn ISeq caching on. (#327, #244)
210
+ * Disable ISeq caching for the whole 2.5.x series again.
211
+ * Better handle hashing of Ruby strings. (#318)
212
+
213
+ # 1.7.0
214
+
215
+ * Fix detection of YAML files in gems.
216
+ * Adds an instrumentation API to monitor cache misses.
217
+ * Allow to control the behavior of `require 'bootsnap/setup'` using environment variables.
218
+ * Deprecate the `disable_trace` option.
219
+ * Deprecate the `ActiveSupport::Dependencies` (AKA Classic autoloader) integration. (#344)
220
+
221
+ # 1.6.0
222
+
223
+ * Fix a Ruby 2.7/3.0 issue with `YAML.load_file` keyword arguments. (#342)
224
+ * `bootsnap precompile` CLI use multiple processes to complete faster. (#341)
225
+ * `bootsnap precompile` CLI also precompile YAML files. (#340)
226
+ * Changed the load path cache directory from `$BOOTSNAP_CACHE_DIR/bootsnap-load-path-cache` to `$BOOTSNAP_CACHE_DIR/bootsnap/load-path-cache` for ease of use. (#334)
227
+ * Changed the compile cache directory from `$BOOTSNAP_CACHE_DIR/bootsnap-compile-cache` to `$BOOTSNAP_CACHE_DIR/bootsnap/compile-cache` for ease of use. (#334)
228
+
229
+ # 1.5.1
230
+
231
+ * Workaround a Ruby bug in InstructionSequence.compile_file. (#332)
232
+
233
+ # 1.5.0
234
+
235
+ * Add a command line to statically precompile the ISeq cache. (#326)
236
+
237
+ # 1.4.9
238
+
239
+ * [Windows support](https://github.com/Shopify/bootsnap/pull/319)
240
+ * [Fix potential crash](https://github.com/Shopify/bootsnap/pull/322)
241
+
242
+ # 1.4.8
243
+
244
+ * [Prevent FallbackScan from polluting exception cause](https://github.com/Shopify/bootsnap/pull/314)
245
+
246
+ # 1.4.7
247
+
248
+ * Various performance enhancements
249
+ * Fix race condition in heavy concurrent load scenarios that would cause bootsnap to raise
250
+
251
+ # 1.4.6
252
+
253
+ * Fix bug that was erroneously considering that files containing `.` in the names were being
254
+ required if a different file with the same name was already being required
255
+
256
+ Example:
257
+
258
+ require 'foo'
259
+ require 'foo.en'
260
+
261
+ Before bootsnap was considering `foo.en` to be the same file as `foo`
262
+
263
+ * Use glibc as part of the ruby_platform cache key
264
+
1
265
  # 1.4.5
2
266
 
3
267
  * MRI 2.7 support
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017 Shopify, Inc.
3
+ Copyright (c) 2017-present Shopify, Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Bootsnap [![Build Status](https://travis-ci.org/Shopify/bootsnap.svg?branch=master)](https://travis-ci.org/Shopify/bootsnap)
1
+ # Bootsnap [![Actions Status](https://github.com/Shopify/bootsnap/workflows/ci/badge.svg)](https://github.com/Shopify/bootsnap/actions)
2
2
 
3
- Bootsnap is a library that plugs into Ruby, with optional support for `ActiveSupport` and `YAML`,
3
+ Bootsnap is a library that plugs into Ruby, with optional support for `YAML` and `JSON`,
4
4
  to optimize and cache expensive computations. See [How Does This Work](#how-does-this-work).
5
5
 
6
6
  #### Performance
@@ -11,7 +11,7 @@ to optimize and cache expensive computations. See [How Does This Work](#how-does
11
11
  - The core Shopify platform -- a rather large monolithic application -- boots about 75% faster,
12
12
  dropping from around 25s to 6.5s.
13
13
  * In Shopify core (a large app), about 25% of this gain can be attributed to `compile_cache_*`
14
- features; 75% to path caching, and ~1% to `disable_trace`. This is fairly representative.
14
+ features; 75% to path caching. This is fairly representative.
15
15
 
16
16
  ## Usage
17
17
 
@@ -29,7 +29,8 @@ If you are using Rails, add this to `config/boot.rb` immediately after `require
29
29
  require 'bootsnap/setup'
30
30
  ```
31
31
 
32
- Note that bootsnap writes to `tmp/cache`, and that directory *must* be writable. Rails will fail to
32
+ Note that bootsnap writes to `tmp/cache` (or the path specified by `ENV['BOOTSNAP_CACHE_DIR']`),
33
+ and that directory *must* be writable. Rails will fail to
33
34
  boot if it is not. If this is unacceptable (e.g. you are running in a read-only container and
34
35
  unwilling to mount in a writable tmpdir), you should remove this line or wrap it in a conditional.
35
36
 
@@ -40,7 +41,7 @@ getting progressively slower, this is almost certainly the cause.**
40
41
  It's technically possible to simply specify `gem 'bootsnap', require: 'bootsnap/setup'`, but it's
41
42
  important to load Bootsnap as early as possible to get maximum performance improvement.
42
43
 
43
- You can see how this require works [here](https://github.com/Shopify/bootsnap/blob/master/lib/bootsnap/setup.rb).
44
+ You can see how this require works [here](https://github.com/Shopify/bootsnap/blob/main/lib/bootsnap/setup.rb).
44
45
 
45
46
  If you are not using Rails, or if you are but want more control over things, add this to your
46
47
  application setup immediately after `require 'bundler/setup'` (i.e. as early as possible: the sooner
@@ -51,17 +52,16 @@ require 'bootsnap'
51
52
  env = ENV['RAILS_ENV'] || "development"
52
53
  Bootsnap.setup(
53
54
  cache_dir: 'tmp/cache', # Path to your cache
55
+ ignore_directories: ['node_modules'], # Directory names to skip.
54
56
  development_mode: env == 'development', # Current working environment, e.g. RACK_ENV, RAILS_ENV, etc
55
57
  load_path_cache: true, # Optimize the LOAD_PATH with a cache
56
- autoload_paths_cache: true, # Optimize ActiveSupport autoloads with cache
57
- disable_trace: true, # Set `RubyVM::InstructionSequence.compile_option = { trace_instruction: false }`
58
58
  compile_cache_iseq: true, # Compile Ruby code into ISeq cache, breaks coverage reporting.
59
- compile_cache_yaml: true # Compile YAML into a cache
59
+ compile_cache_yaml: true, # Compile YAML into a cache
60
+ compile_cache_json: true, # Compile JSON into a cache
61
+ readonly: true, # Use the caches but don't update them on miss or stale entries.
60
62
  )
61
63
  ```
62
64
 
63
- **Note that `disable_trace` will break debuggers and tracing.**
64
-
65
65
  **Protip:** You can replace `require 'bootsnap'` with `BootLib::Require.from_gem('bootsnap',
66
66
  'bootsnap')` using [this trick](https://github.com/Shopify/bootsnap/wiki/Bootlib::Require). This
67
67
  will help optimize boot time further if you have an extremely large `$LOAD_PATH`.
@@ -69,7 +69,22 @@ will help optimize boot time further if you have an extremely large `$LOAD_PATH`
69
69
  Note: Bootsnap and [Spring](https://github.com/rails/spring) are orthogonal tools. While Bootsnap
70
70
  speeds up the loading of individual source files, Spring keeps a copy of a pre-booted Rails process
71
71
  on hand to completely skip parts of the boot process the next time it's needed. The two tools work
72
- well together, and are both included in a newly-generated Rails applications by default.
72
+ well together.
73
+
74
+ ### Environment variables
75
+
76
+ `require 'bootsnap/setup'` behavior can be changed using environment variables:
77
+
78
+ - `BOOTSNAP_CACHE_DIR` allows to define the cache location.
79
+ - `DISABLE_BOOTSNAP` allows to entirely disable bootsnap.
80
+ - `DISABLE_BOOTSNAP_LOAD_PATH_CACHE` allows to disable load path caching.
81
+ - `DISABLE_BOOTSNAP_COMPILE_CACHE` allows to disable ISeq and YAML caches.
82
+ - `BOOTSNAP_READONLY` configure bootsnap to not update the cache on miss or stale entries.
83
+ - `BOOTSNAP_LOG` configure bootsnap to log all caches misses to STDERR.
84
+ - `BOOTSNAP_STATS` log hit rate statistics on exit. Can't be used if `BOOTSNAP_LOG` is enabled.
85
+ - `BOOTSNAP_IGNORE_DIRECTORIES` a comma separated list of directories that shouldn't be scanned.
86
+ Useful when you have large directories of non-ruby files inside `$LOAD_PATH`.
87
+ It defaults to ignore any directory named `node_modules`.
73
88
 
74
89
  ### Environments
75
90
 
@@ -77,6 +92,23 @@ All Bootsnap features are enabled in development, test, production, and all othe
77
92
 
78
93
  If you would like to disable any feature for a certain environment, we suggest changing the configuration to take into account the appropriate ENV var or configuration according to your needs.
79
94
 
95
+ ### Instrumentation
96
+
97
+ Bootsnap cache misses can be monitored though a callback:
98
+
99
+ ```ruby
100
+ Bootsnap.instrumentation = ->(event, path) { puts "#{event} #{path}" }
101
+ ```
102
+
103
+ `event` is either `:hit`, `:miss`, `:stale` or `:revalidated`.
104
+ You can also call `Bootsnap.log!` as a shortcut to log all events to STDERR.
105
+
106
+ To turn instrumentation back off you can set it to nil:
107
+
108
+ ```ruby
109
+ Bootsnap.instrumentation = nil
110
+ ```
111
+
80
112
  ## How does this work?
81
113
 
82
114
  Bootsnap optimizes methods to cache results of expensive computations, and can be grouped
@@ -84,13 +116,12 @@ into two broad categories:
84
116
 
85
117
  * [Path Pre-Scanning](#path-pre-scanning)
86
118
  * `Kernel#require` and `Kernel#load` are modified to eliminate `$LOAD_PATH` scans.
87
- * `ActiveSupport::Dependencies.{autoloadable_module?,load_missing_constant,depend_on}` are
88
- overridden to eliminate scans of `ActiveSupport::Dependencies.autoload_paths`.
89
119
  * [Compilation caching](#compilation-caching)
90
120
  * `RubyVM::InstructionSequence.load_iseq` is implemented to cache the result of ruby bytecode
91
121
  compilation.
92
122
  * `YAML.load_file` is modified to cache the result of loading a YAML object in MessagePack format
93
123
  (or Marshal, if the message uses types unsupported by MessagePack).
124
+ * `JSON.load_file` is modified to cache the result of loading a JSON object in MessagePack format
94
125
 
95
126
  ### Path Pre-Scanning
96
127
 
@@ -124,10 +155,6 @@ open y/foo.rb
124
155
  ...
125
156
  ```
126
157
 
127
- Exactly the same strategy is employed for methods that traverse
128
- `ActiveSupport::Dependencies.autoload_paths` if the `autoload_paths_cache` option is given to
129
- `Bootsnap.setup`.
130
-
131
158
  The following diagram flowcharts the overrides that make the `*_path_cache` features work.
132
159
 
133
160
  ![Flowchart explaining
@@ -143,7 +170,7 @@ The only directories considered "stable" are things under the Ruby install prefi
143
170
  "volatile".
144
171
 
145
172
  In addition to the [`Bootsnap::LoadPathCache::Cache`
146
- source](https://github.com/Shopify/bootsnap/blob/master/lib/bootsnap/load_path_cache/cache.rb),
173
+ source](https://github.com/Shopify/bootsnap/blob/main/lib/bootsnap/load_path_cache/cache.rb),
147
174
  this diagram may help clarify how entry resolution works:
148
175
 
149
176
  ![How path searching works](https://cloud.githubusercontent.com/assets/3074765/25388270/670b5652-299b-11e7-87fb-975647f68981.png)
@@ -165,9 +192,9 @@ translated ruby source to an internal bytecode format, which is then executed by
165
192
  allows caching that bytecode. This allows us to bypass the relatively-expensive compilation step on
166
193
  subsequent loads of the same file.
167
194
 
168
- We also noticed that we spend a lot of time loading YAML documents during our application boot, and
169
- that MessagePack and Marshal are *much* faster at deserialization than YAML, even with a fast
170
- implementation. We use the same strategy of compilation caching for YAML documents, with the
195
+ We also noticed that we spend a lot of time loading YAML and JSON documents during our application boot, and
196
+ that MessagePack and Marshal are *much* faster at deserialization than YAML and JSON, even with a fast
197
+ implementation. We use the same strategy of compilation caching for YAML and JSON documents, with the
171
198
  equivalent of Ruby's "bytecode" format being a MessagePack document (or, in the case of YAML
172
199
  documents with types unsupported by MessagePack, a Marshal stream).
173
200
 
@@ -214,9 +241,9 @@ Bootsnap writes a cache file containing a 64 byte header followed by the cache c
214
241
  is a cache key including several fields:
215
242
 
216
243
  * `version`, hardcoded in bootsnap. Essentially a schema version;
217
- * `os_version`, A hash of the current kernel version (on macOS, BSD) or glibc version (on Linux);
244
+ * `ruby_platform`, A hash of `RUBY_PLATFORM` (e.g. x86_64-linux-gnu) variable.
218
245
  * `compile_option`, which changes with `RubyVM::InstructionSequence.compile_option` does;
219
- * `ruby_revision`, the version of Ruby this was compiled with;
246
+ * `ruby_revision`, A hash of `RUBY_REVISION`, the exact version of Ruby;
220
247
  * `size`, the size of the source file;
221
248
  * `mtime`, the last-modification timestamp of the source file when it was compiled; and
222
249
  * `data_size`, the number of bytes following the header, which we need to read it into a buffer.
@@ -294,6 +321,19 @@ open /c/nope.bundle -> -1
294
321
  # (nothing!)
295
322
  ```
296
323
 
324
+ ## Precompilation
325
+
326
+ In development environments the bootsnap compilation cache is generated on the fly when source files are loaded.
327
+ But in production environments, such as docker images, you might need to precompile the cache.
328
+
329
+ To do so you can use the `bootsnap precompile` command.
330
+
331
+ Example:
332
+
333
+ ```bash
334
+ $ bundle exec bootsnap precompile --gemfile app/ lib/
335
+ ```
336
+
297
337
  ## When not to use Bootsnap
298
338
 
299
339
  *Alternative engines*: Bootsnap is pretty reliant on MRI features, and parts are disabled entirely on alternative ruby
data/exe/bootsnap ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bootsnap/cli"
5
+ exit Bootsnap::CLI.new(ARGV).run