bootsnap 1.18.0 → 1.18.2

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: 52fa7adde2726e79c8d06b4ca8a450d0ecc0fd143b377a0da3aa27965e5ecd52
4
- data.tar.gz: 7029e821fbd1da561f14fce91cc3ca72f8ee80eb6ead5a099bc37b74233c9dce
3
+ metadata.gz: 219e1686c3d7b3a3c3d0e4814c27842f1e1e9ab35958a1a655532ccaedfa4702
4
+ data.tar.gz: 439966933d2dea1cf428b6b61d5e8e72e3c9e7963a00938aff46622a5f7342bf
5
5
  SHA512:
6
- metadata.gz: bce0d723ae15e1fcc8961b698977977a49587d4fe514c76dd10d97453808c6562681e9df80dd3ecec2f1eff70f8a54592027c699d37c4c39e9254c6b63507f6b
7
- data.tar.gz: 8272f4541d3789e8eb390319ec04d202b90fc0745696f73d414a7dc1365380246ec7b44746b3592abf19883eae709f2daf4e5033677b7be3490dc0ad642fb6d7
6
+ metadata.gz: 6232067f5e67dc414233738b2d1e6390cf17726d78efe6150d30ccd7b7d2e206c68515ddb182988537331982e206be60e3c974fba779ca98a42810084507a827
7
+ data.tar.gz: 6d7aa8fc570210a4798903e6150a5e97de4d67e29729c8a04db3ca2aae7bd47f3d9257e8b961158155103306e4ec99f8d50a94cac2c2798c86471d7219038d49
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Unreleased
2
2
 
3
+ # 1.18.2
4
+
5
+ * Disable stale cache entries revalidation by default as it seems to cause cache corruption issues. See #471 and #474.
6
+ Will be re-enabled in a future version once the root cause is identified.
7
+ * Fix a potential compilation issue on some systems. See #470.
8
+
9
+ # 1.18.1
10
+
11
+ * Handle `EPERM` errors when opening files with `O_NOATIME`.
12
+
3
13
  # 1.18.0
4
14
 
5
15
  * `Bootsnap.instrumentation` now receive `:hit` events.
@@ -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,10 +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;
107
+ static bool perm_issue = false;
99
108
 
100
109
  /* Functions exposed as module functions on Bootsnap::CompileCache::Native */
101
110
  static VALUE bs_instrumentation_enabled_set(VALUE self, VALUE enabled);
102
111
  static VALUE bs_readonly_set(VALUE self, VALUE enabled);
112
+ static VALUE bs_revalidation_set(VALUE self, VALUE enabled);
103
113
  static VALUE bs_compile_option_crc32_set(VALUE self, VALUE crc32_v);
104
114
  static VALUE bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler, VALUE args);
105
115
  static VALUE bs_rb_precompile(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler);
@@ -119,7 +129,7 @@ static int update_cache_key(struct bs_cache_key *current_key, int cache_fd, cons
119
129
  static void bs_cache_key_digest(struct bs_cache_key * key, const VALUE input_data);
120
130
  static VALUE bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args);
121
131
  static VALUE bs_precompile(char * path, VALUE path_v, char * cache_path, VALUE handler);
122
- static int open_current_file(char * path, struct bs_cache_key * key, const char ** errno_provenance);
132
+ static int open_current_file(const char * path, struct bs_cache_key * key, const char ** errno_provenance);
123
133
  static int fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE * output_data, int * exception_tag, const char ** errno_provenance);
124
134
  static uint32_t get_ruby_revision(void);
125
135
  static uint32_t get_ruby_platform(void);
@@ -182,6 +192,7 @@ Init_bootsnap(void)
182
192
 
183
193
  rb_define_module_function(rb_mBootsnap, "instrumentation_enabled=", bs_instrumentation_enabled_set, 1);
184
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);
185
196
  rb_define_module_function(rb_mBootsnap_CompileCache_Native, "coverage_running?", bs_rb_coverage_running, 0);
186
197
  rb_define_module_function(rb_mBootsnap_CompileCache_Native, "fetch", bs_rb_fetch, 4);
187
198
  rb_define_module_function(rb_mBootsnap_CompileCache_Native, "precompile", bs_rb_precompile, 3);
@@ -213,6 +224,13 @@ bs_readonly_set(VALUE self, VALUE enabled)
213
224
  return enabled;
214
225
  }
215
226
 
227
+ static VALUE
228
+ bs_revalidation_set(VALUE self, VALUE enabled)
229
+ {
230
+ revalidation = RTEST(enabled);
231
+ return enabled;
232
+ }
233
+
216
234
  /*
217
235
  * Bootsnap's ruby code registers a hook that notifies us via this function
218
236
  * when compile_option changes. These changes invalidate all existing caches.
@@ -317,7 +335,12 @@ static enum cache_status cache_key_equal_fast_path(struct bs_cache_key *k1,
317
335
  k1->ruby_platform == k2->ruby_platform &&
318
336
  k1->compile_option == k2->compile_option &&
319
337
  k1->ruby_revision == k2->ruby_revision && k1->size == k2->size) {
320
- return (k1->mtime == k2->mtime) ? hit : stale;
338
+ if (k1->mtime == k2->mtime) {
339
+ return hit;
340
+ }
341
+ if (revalidation) {
342
+ return stale;
343
+ }
321
344
  }
322
345
  return miss;
323
346
  }
@@ -413,17 +436,34 @@ bs_rb_precompile(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler)
413
436
 
414
437
  return bs_precompile(path, path_v, cache_path, handler);
415
438
  }
439
+
440
+ static int bs_open_noatime(const char *path, int flags) {
441
+ int fd = 1;
442
+ if (!perm_issue) {
443
+ fd = open(path, flags | O_NOATIME);
444
+ if (fd < 0 && errno == EPERM) {
445
+ errno = 0;
446
+ perm_issue = true;
447
+ }
448
+ }
449
+
450
+ if (perm_issue) {
451
+ fd = open(path, flags);
452
+ }
453
+ return fd;
454
+ }
455
+
416
456
  /*
417
457
  * Open the file we want to load/cache and generate a cache key for it if it
418
458
  * was loaded.
419
459
  */
420
460
  static int
421
- open_current_file(char * path, struct bs_cache_key * key, const char ** errno_provenance)
461
+ open_current_file(const char * path, struct bs_cache_key * key, const char ** errno_provenance)
422
462
  {
423
463
  struct stat statbuf;
424
464
  int fd;
425
465
 
426
- fd = open(path, O_RDONLY | O_NOATIME);
466
+ fd = bs_open_noatime(path, O_RDONLY);
427
467
  if (fd < 0) {
428
468
  *errno_provenance = "bs_fetch:open_current_file:open";
429
469
  return fd;
@@ -490,10 +530,10 @@ open_cache_file(const char * path, struct bs_cache_key * key, const char ** errn
490
530
  {
491
531
  int fd, res;
492
532
 
493
- if (readonly) {
494
- fd = open(path, O_RDONLY | O_NOATIME);
533
+ if (readonly || !revalidation) {
534
+ fd = bs_open_noatime(path, O_RDONLY);
495
535
  } else {
496
- fd = open(path, O_RDWR | O_NOATIME);
536
+ fd = bs_open_noatime(path, O_RDWR);
497
537
  }
498
538
 
499
539
  if (fd < 0) {
@@ -890,6 +930,12 @@ succeed:
890
930
  return output_data;
891
931
  fail_errno:
892
932
  CLEANUP;
933
+ if (errno_provenance) {
934
+ exception_message = rb_str_concat(
935
+ rb_str_new_cstr(errno_provenance),
936
+ rb_str_concat(rb_str_new_cstr(": "), exception_message)
937
+ );
938
+ }
893
939
  exception = rb_syserr_new_str(errno, exception_message);
894
940
  rb_exc_raise(exception);
895
941
  __builtin_unreachable();
@@ -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.0"
4
+ VERSION = "1.18.2"
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.0
4
+ version: 1.18.2
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