bootsnap 1.4.5 → 1.18.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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