bootsnap 1.18.1 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69d7ab3b264f447ac2a6a3ccea6a4cb27e6fa0ce6b50e6fef645c21d41a89a07
4
- data.tar.gz: 595c8df291862a529b9a679f36bcae270c5d0efeee22b2fa68f1d7fc78cd7a86
3
+ metadata.gz: 4fa4ab785277ee01a1c8ee75b43f0efb93db42bffcdacc1c8505a65efa03dede
4
+ data.tar.gz: 8aaaca48ae257b563580023c8fa36a59463f4c30f5463c14f6b8b94bf5fe27df
5
5
  SHA512:
6
- metadata.gz: 38b9b648b181ca689c3ed64b5f01ad2bb1f41c0b51f241eed19b9d5b2fc93247b37fef4e507981b3e606f4d4b1840b2c57a0ef9656d36fbc398f14e725549235
7
- data.tar.gz: e72104154d6b9bd688a2290e1704546e9dd08f792e2bf34d1a02329578e694c9849e79f3f62f197093ab42a06f8328028426cc0676b6c4c2a3a565ebd586bd44
6
+ metadata.gz: 27b48d27d3330c8565952a2fbb979e71013b1e9585bcb3284656192808c304f2874c32a135b14895eec61a7ef038fa71fa111964a56e7aaedc9ff507ef307686
7
+ data.tar.gz: c3d83a0b068f2908a6298c7cd8e1a660f1228a7ddbfb9409cb3f6c174319f3974388ce73756c04062b17b97a37e199a07bccbb0b8dc1c6224998c58c51194b27
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Unreleased
2
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
+
3
14
  # 1.18.1
4
15
 
5
16
  * Handle `EPERM` errors when opening files with `O_NOATIME`.
@@ -18,8 +18,15 @@
18
18
  #include <sys/types.h>
19
19
  #include <errno.h>
20
20
  #include <fcntl.h>
21
+ #include <unistd.h>
21
22
  #include <sys/stat.h>
22
23
 
24
+ #ifdef __APPLE__
25
+ // The symbol is present, however not in the headers
26
+ // See: https://github.com/Shopify/bootsnap/issues/470
27
+ extern int fdatasync(int);
28
+ #endif
29
+
23
30
  #ifndef O_NOATIME
24
31
  #define O_NOATIME 0
25
32
  #endif
@@ -96,11 +103,13 @@ static ID instrumentation_method;
96
103
  static VALUE sym_hit, sym_miss, sym_stale, sym_revalidated;
97
104
  static bool instrumentation_enabled = false;
98
105
  static bool readonly = false;
106
+ static bool revalidation = false;
99
107
  static bool perm_issue = false;
100
108
 
101
109
  /* Functions exposed as module functions on Bootsnap::CompileCache::Native */
102
110
  static VALUE bs_instrumentation_enabled_set(VALUE self, VALUE enabled);
103
111
  static VALUE bs_readonly_set(VALUE self, VALUE enabled);
112
+ static VALUE bs_revalidation_set(VALUE self, VALUE enabled);
104
113
  static VALUE bs_compile_option_crc32_set(VALUE self, VALUE crc32_v);
105
114
  static VALUE bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler, VALUE args);
106
115
  static VALUE bs_rb_precompile(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler);
@@ -115,7 +124,7 @@ static void bs_cache_path(const char * cachedir, const VALUE path, char (* cache
115
124
  static int bs_read_key(int fd, struct bs_cache_key * key);
116
125
  static enum cache_status cache_key_equal_fast_path(struct bs_cache_key * k1, struct bs_cache_key * k2);
117
126
  static int cache_key_equal_slow_path(struct bs_cache_key * current_key, struct bs_cache_key * cached_key, const VALUE input_data);
118
- static int update_cache_key(struct bs_cache_key *current_key, int cache_fd, const char ** errno_provenance);
127
+ static int update_cache_key(struct bs_cache_key *current_key, struct bs_cache_key *old_key, int cache_fd, const char ** errno_provenance);
119
128
 
120
129
  static void bs_cache_key_digest(struct bs_cache_key * key, const VALUE input_data);
121
130
  static VALUE bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args);
@@ -183,6 +192,7 @@ Init_bootsnap(void)
183
192
 
184
193
  rb_define_module_function(rb_mBootsnap, "instrumentation_enabled=", bs_instrumentation_enabled_set, 1);
185
194
  rb_define_module_function(rb_mBootsnap_CompileCache_Native, "readonly=", bs_readonly_set, 1);
195
+ rb_define_module_function(rb_mBootsnap_CompileCache_Native, "revalidation=", bs_revalidation_set, 1);
186
196
  rb_define_module_function(rb_mBootsnap_CompileCache_Native, "coverage_running?", bs_rb_coverage_running, 0);
187
197
  rb_define_module_function(rb_mBootsnap_CompileCache_Native, "fetch", bs_rb_fetch, 4);
188
198
  rb_define_module_function(rb_mBootsnap_CompileCache_Native, "precompile", bs_rb_precompile, 3);
@@ -214,6 +224,13 @@ bs_readonly_set(VALUE self, VALUE enabled)
214
224
  return enabled;
215
225
  }
216
226
 
227
+ static VALUE
228
+ bs_revalidation_set(VALUE self, VALUE enabled)
229
+ {
230
+ revalidation = RTEST(enabled);
231
+ return enabled;
232
+ }
233
+
217
234
  /*
218
235
  * Bootsnap's ruby code registers a hook that notifies us via this function
219
236
  * when compile_option changes. These changes invalidate all existing caches.
@@ -318,7 +335,12 @@ static enum cache_status cache_key_equal_fast_path(struct bs_cache_key *k1,
318
335
  k1->ruby_platform == k2->ruby_platform &&
319
336
  k1->compile_option == k2->compile_option &&
320
337
  k1->ruby_revision == k2->ruby_revision && k1->size == k2->size) {
321
- return (k1->mtime == k2->mtime) ? hit : stale;
338
+ if (k1->mtime == k2->mtime) {
339
+ return hit;
340
+ }
341
+ if (revalidation) {
342
+ return stale;
343
+ }
322
344
  }
323
345
  return miss;
324
346
  }
@@ -331,10 +353,11 @@ static int cache_key_equal_slow_path(struct bs_cache_key *current_key,
331
353
  return current_key->digest == cached_key->digest;
332
354
  }
333
355
 
334
- static int update_cache_key(struct bs_cache_key *current_key, int cache_fd, const char ** errno_provenance)
356
+ static int update_cache_key(struct bs_cache_key *current_key, struct bs_cache_key *old_key, int cache_fd, const char ** errno_provenance)
335
357
  {
358
+ old_key->mtime = current_key->mtime;
336
359
  lseek(cache_fd, 0, SEEK_SET);
337
- ssize_t nwrite = write(cache_fd, current_key, KEY_SIZE);
360
+ ssize_t nwrite = write(cache_fd, old_key, KEY_SIZE);
338
361
  if (nwrite < 0) {
339
362
  *errno_provenance = "update_cache_key:write";
340
363
  return -1;
@@ -508,7 +531,7 @@ open_cache_file(const char * path, struct bs_cache_key * key, const char ** errn
508
531
  {
509
532
  int fd, res;
510
533
 
511
- if (readonly) {
534
+ if (readonly || !revalidation) {
512
535
  fd = bs_open_noatime(path, O_RDONLY);
513
536
  } else {
514
537
  fd = bs_open_noatime(path, O_RDWR);
@@ -803,7 +826,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
803
826
  valid_cache = cache_key_equal_slow_path(&current_key, &cached_key, input_data);
804
827
  if (valid_cache) {
805
828
  if (!readonly) {
806
- if (update_cache_key(&current_key, cache_fd, &errno_provenance)) {
829
+ if (update_cache_key(&current_key, &cached_key, cache_fd, &errno_provenance)) {
807
830
  exception_message = path_v;
808
831
  goto fail_errno;
809
832
  }
@@ -908,6 +931,12 @@ succeed:
908
931
  return output_data;
909
932
  fail_errno:
910
933
  CLEANUP;
934
+ if (errno_provenance) {
935
+ exception_message = rb_str_concat(
936
+ rb_str_new_cstr(errno_provenance),
937
+ rb_str_concat(rb_str_new_cstr(": "), exception_message)
938
+ );
939
+ }
911
940
  exception = rb_syserr_new_str(errno, exception_message);
912
941
  rb_exc_raise(exception);
913
942
  __builtin_unreachable();
@@ -965,7 +994,7 @@ bs_precompile(char * path, VALUE path_v, char * cache_path, VALUE handler)
965
994
  }
966
995
  valid_cache = cache_key_equal_slow_path(&current_key, &cached_key, input_data);
967
996
  if (valid_cache) {
968
- if (update_cache_key(&current_key, cache_fd, &errno_provenance)) {
997
+ if (update_cache_key(&current_key, &cached_key, cache_fd, &errno_provenance)) {
969
998
  goto fail;
970
999
  }
971
1000
  }
@@ -3,10 +3,10 @@
3
3
  require "mkmf"
4
4
 
5
5
  if %w[ruby truffleruby].include?(RUBY_ENGINE)
6
- have_func "fdatasync", "fcntl.h"
6
+ have_func "fdatasync", "unistd.h"
7
7
 
8
8
  unless RUBY_PLATFORM.match?(/mswin|mingw|cygwin/)
9
- append_cppflags ["_GNU_SOURCE"] # Needed of O_NOATIME
9
+ append_cppflags ["-D_GNU_SOURCE"] # Needed of O_NOATIME
10
10
  end
11
11
 
12
12
  append_cflags ["-O3", "-std=c99"]
@@ -9,7 +9,7 @@ module Bootsnap
9
9
 
10
10
  Error = Class.new(StandardError)
11
11
 
12
- def self.setup(cache_dir:, iseq:, yaml:, json:, readonly: false)
12
+ def self.setup(cache_dir:, iseq:, yaml:, json:, readonly: false, revalidation: false)
13
13
  if iseq
14
14
  if supported?
15
15
  require_relative "compile_cache/iseq"
@@ -39,6 +39,7 @@ module Bootsnap
39
39
 
40
40
  if supported? && defined?(Bootsnap::CompileCache::Native)
41
41
  Bootsnap::CompileCache::Native.readonly = readonly
42
+ Bootsnap::CompileCache::Native.revalidation = revalidation
42
43
  end
43
44
  end
44
45
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bootsnap
4
- VERSION = "1.18.1"
4
+ VERSION = "1.18.3"
5
5
  end
data/lib/bootsnap.rb CHANGED
@@ -51,6 +51,7 @@ module Bootsnap
51
51
  load_path_cache: true,
52
52
  ignore_directories: nil,
53
53
  readonly: false,
54
+ revalidation: false,
54
55
  compile_cache_iseq: true,
55
56
  compile_cache_yaml: true,
56
57
  compile_cache_json: true
@@ -70,6 +71,7 @@ module Bootsnap
70
71
  yaml: compile_cache_yaml,
71
72
  json: compile_cache_json,
72
73
  readonly: readonly,
74
+ revalidation: revalidation,
73
75
  )
74
76
  end
75
77
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootsnap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.18.1
4
+ version: 1.18.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-30 00:00:00.000000000 Z
11
+ date: 2024-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack