bootsnap 1.18.1 → 1.18.3

Sign up to get free protection for your applications and to get access to all the features.
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