Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package rubygem-bootsnap for
openSUSE:Factory checked in at 2024-06-24 20:54:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-bootsnap (Old)
and /work/SRC/openSUSE:Factory/.rubygem-bootsnap.new.18349 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-bootsnap"
Mon Jun 24 20:54:50 2024 rev:24 rq:1182765 version:1.18.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-bootsnap/rubygem-bootsnap.changes
2024-02-26 19:49:43.651315299 +0100
+++
/work/SRC/openSUSE:Factory/.rubygem-bootsnap.new.18349/rubygem-bootsnap.changes
2024-06-24 20:56:25.715156968 +0200
@@ -1,0 +2,29 @@
+Fri Jun 21 09:33:29 UTC 2024 - Dan Äermák <[email protected]>
+
+- # 1.18.3
+
+* Fix the cache corruption issue in the revalidation feature. See #474.
+ The cache revalidation feature remains opt-in for now, until it is more
battle tested.
+
+# 1.18.2
+
+* Disable stale cache entries revalidation by default as it seems to cause
cache corruption issues. See #471 and #474.
+ Will be re-enabled in a future version once the root cause is identified.
+* Fix a potential compilation issue on some systems. See #470.
+
+# 1.18.1
+
+* Handle `EPERM` errors when opening files with `O_NOATIME`.
+
+# 1.18.0
+
+* `Bootsnap.instrumentation` now receive `:hit` events.
+* Add `Bootsnap.log_stats!` to print hit rate statistics on process exit. Can
also be enabled with `BOOTSNAP_STATS=1`.
+* Revalidate stale cache entries by digesting the source content.
+ This should significantly improve performance in environments where `mtime`
isn't preserved (e.g. CI systems doing a git clone, etc).
+ See #468.
+* Open source files and cache entries with `O_NOATIME` when available to
reduce disk accesses. See #469.
+* `bootsnap precompile --gemfile` now look for `.rb` files in the whole gem
and not just the `lib/` directory. See #466.
+
+
+-------------------------------------------------------------------
Old:
----
bootsnap-1.17.1.gem
New:
----
bootsnap-1.18.3.gem
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ rubygem-bootsnap.spec ++++++
--- /var/tmp/diff_new_pack.jiQa2n/_old 2024-06-24 20:56:27.179210526 +0200
+++ /var/tmp/diff_new_pack.jiQa2n/_new 2024-06-24 20:56:27.195211111 +0200
@@ -24,7 +24,7 @@
#
Name: rubygem-bootsnap
-Version: 1.17.1
+Version: 1.18.3
Release: 0
%define mod_name bootsnap
%define mod_full_name %{mod_name}-%{version}
++++++ bootsnap-1.17.1.gem -> bootsnap-1.18.3.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md
--- old/CHANGELOG.md 2024-01-12 12:03:46.000000000 +0100
+++ new/CHANGELOG.md 2024-01-31 15:42:25.000000000 +0100
@@ -1,5 +1,30 @@
# Unreleased
+# 1.18.3
+
+* Fix the cache corruption issue in the revalidation feature. See #474.
+ The cache revalidation feature remains opt-in for now, until it is more
battle tested.
+
+# 1.18.2
+
+* Disable stale cache entries revalidation by default as it seems to cause
cache corruption issues. See #471 and #474.
+ Will be re-enabled in a future version once the root cause is identified.
+* Fix a potential compilation issue on some systems. See #470.
+
+# 1.18.1
+
+* Handle `EPERM` errors when opening files with `O_NOATIME`.
+
+# 1.18.0
+
+* `Bootsnap.instrumentation` now receive `:hit` events.
+* Add `Bootsnap.log_stats!` to print hit rate statistics on process exit. Can
also be enabled with `BOOTSNAP_STATS=1`.
+* Revalidate stale cache entries by digesting the source content.
+ This should significantly improve performance in environments where `mtime`
isn't preserved (e.g. CI systems doing a git clone, etc).
+ See #468.
+* Open source files and cache entries with `O_NOATIME` when available to
reduce disk accesses. See #469.
+* `bootsnap precompile --gemfile` now look for `.rb` files in the whole gem
and not just the `lib/` directory. See #466.
+
# 1.17.1
* Fix a compatibility issue with the `prism` library that ships with Ruby 3.3.
See #463.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md 2024-01-12 12:03:46.000000000 +0100
+++ new/README.md 2024-01-31 15:42:25.000000000 +0100
@@ -81,6 +81,7 @@
- `DISABLE_BOOTSNAP_COMPILE_CACHE` allows to disable ISeq and YAML caches.
- `BOOTSNAP_READONLY` configure bootsnap to not update the cache on miss or
stale entries.
- `BOOTSNAP_LOG` configure bootsnap to log all caches misses to STDERR.
+- `BOOTSNAP_STATS` log hit rate statistics on exit. Can't be used if
`BOOTSNAP_LOG` is enabled.
- `BOOTSNAP_IGNORE_DIRECTORIES` a comma separated list of directories that
shouldn't be scanned.
Useful when you have large directories of non-ruby files inside `$LOAD_PATH`.
It defaults to ignore any directory named `node_modules`.
@@ -99,8 +100,8 @@
Bootsnap.instrumentation = ->(event, path) { puts "#{event} #{path}" }
```
-`event` is either `:miss` or `:stale`. You can also call `Bootsnap.log!` as a
shortcut to
-log all events to STDERR.
+`event` is either `:hit`, `:miss`, `:stale` or `:revalidated`.
+You can also call `Bootsnap.log!` as a shortcut to log all events to STDERR.
To turn instrumentation back off you can set it to nil:
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ext/bootsnap/bootsnap.c new/ext/bootsnap/bootsnap.c
--- old/ext/bootsnap/bootsnap.c 2024-01-12 12:03:46.000000000 +0100
+++ new/ext/bootsnap/bootsnap.c 2024-01-31 15:42:25.000000000 +0100
@@ -18,8 +18,19 @@
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
+#include <unistd.h>
#include <sys/stat.h>
+#ifdef __APPLE__
+ // The symbol is present, however not in the headers
+ // See: https://github.com/Shopify/bootsnap/issues/470
+ extern int fdatasync(int);
+#endif
+
+#ifndef O_NOATIME
+#define O_NOATIME 0
+#endif
+
/* 1000 is an arbitrary limit; FNV64 plus some slashes brings the cap down to
* 981 for the cache dir */
#define MAX_CACHEPATH_SIZE 1000
@@ -30,7 +41,7 @@
#define MAX_CREATE_TEMPFILE_ATTEMPT 3
#ifndef RB_UNLIKELY
- #define RB_UNLIKELY(x) (x)
+#define RB_UNLIKELY(x) (x)
#endif
/*
@@ -54,8 +65,10 @@
uint32_t ruby_revision;
uint64_t size;
uint64_t mtime;
- uint64_t data_size; /* not used for equality */
- uint8_t pad[24];
+ uint64_t data_size; //
+ uint64_t digest;
+ uint8_t digest_set;
+ uint8_t pad[15];
} __attribute__((packed));
/*
@@ -69,7 +82,7 @@
STATIC_ASSERT(sizeof(struct bs_cache_key) == KEY_SIZE);
/* Effectively a schema version. Bumping invalidates all previous caches */
-static const uint32_t current_version = 4;
+static const uint32_t current_version = 5;
/* hash of e.g. "x86_64-darwin17", invalidating when ruby is recompiled on a
* new OS ABI, etc. */
@@ -87,25 +100,36 @@
static VALUE rb_mBootsnap_CompileCache_Native;
static VALUE rb_cBootsnap_CompileCache_UNCOMPILABLE;
static ID instrumentation_method;
-static VALUE sym_miss;
-static VALUE sym_stale;
+static VALUE sym_hit, sym_miss, sym_stale, sym_revalidated;
static bool instrumentation_enabled = false;
static bool readonly = false;
+static bool revalidation = false;
+static bool perm_issue = false;
/* Functions exposed as module functions on Bootsnap::CompileCache::Native */
static VALUE bs_instrumentation_enabled_set(VALUE self, VALUE enabled);
static VALUE bs_readonly_set(VALUE self, VALUE enabled);
+static VALUE bs_revalidation_set(VALUE self, VALUE enabled);
static VALUE bs_compile_option_crc32_set(VALUE self, VALUE crc32_v);
static VALUE bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE
handler, VALUE args);
static VALUE bs_rb_precompile(VALUE self, VALUE cachedir_v, VALUE path_v,
VALUE handler);
/* Helpers */
+enum cache_status {
+ miss,
+ hit,
+ stale,
+};
static void bs_cache_path(const char * cachedir, const VALUE path, char (*
cache_path)[MAX_CACHEPATH_SIZE]);
static int bs_read_key(int fd, struct bs_cache_key * key);
-static int cache_key_equal(struct bs_cache_key * k1, struct bs_cache_key * k2);
+static enum cache_status cache_key_equal_fast_path(struct bs_cache_key * k1,
struct bs_cache_key * k2);
+static int cache_key_equal_slow_path(struct bs_cache_key * current_key, struct
bs_cache_key * cached_key, const VALUE input_data);
+static int update_cache_key(struct bs_cache_key *current_key, struct
bs_cache_key *old_key, int cache_fd, const char ** errno_provenance);
+
+static void bs_cache_key_digest(struct bs_cache_key * key, const VALUE
input_data);
static VALUE bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE
handler, VALUE args);
static VALUE bs_precompile(char * path, VALUE path_v, char * cache_path, VALUE
handler);
-static int open_current_file(char * path, struct bs_cache_key * key, const
char ** errno_provenance);
+static int open_current_file(const char * path, struct bs_cache_key * key,
const char ** errno_provenance);
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);
static uint32_t get_ruby_revision(void);
static uint32_t get_ruby_platform(void);
@@ -161,14 +185,14 @@
instrumentation_method = rb_intern("_instrument");
+ sym_hit = ID2SYM(rb_intern("hit"));
sym_miss = ID2SYM(rb_intern("miss"));
- rb_global_variable(&sym_miss);
-
sym_stale = ID2SYM(rb_intern("stale"));
- rb_global_variable(&sym_stale);
+ sym_revalidated = ID2SYM(rb_intern("revalidated"));
rb_define_module_function(rb_mBootsnap, "instrumentation_enabled=",
bs_instrumentation_enabled_set, 1);
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "readonly=",
bs_readonly_set, 1);
+ rb_define_module_function(rb_mBootsnap_CompileCache_Native, "revalidation=",
bs_revalidation_set, 1);
rb_define_module_function(rb_mBootsnap_CompileCache_Native,
"coverage_running?", bs_rb_coverage_running, 0);
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "fetch",
bs_rb_fetch, 4);
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "precompile",
bs_rb_precompile, 3);
@@ -185,6 +209,14 @@
return enabled;
}
+static inline void
+bs_instrumentation(VALUE event, VALUE path)
+{
+ if (RB_UNLIKELY(instrumentation_enabled)) {
+ rb_funcall(rb_mBootsnap, instrumentation_method, 2, event, path);
+ }
+}
+
static VALUE
bs_readonly_set(VALUE self, VALUE enabled)
{
@@ -192,6 +224,13 @@
return enabled;
}
+static VALUE
+bs_revalidation_set(VALUE self, VALUE enabled)
+{
+ revalidation = RTEST(enabled);
+ return enabled;
+}
+
/*
* Bootsnap's ruby code registers a hook that notifies us via this function
* when compile_option changes. These changes invalidate all existing caches.
@@ -290,17 +329,59 @@
* The data_size member is not compared, as it serves more of a "header"
* function.
*/
-static int
-cache_key_equal(struct bs_cache_key * k1, struct bs_cache_key * k2)
+static enum cache_status cache_key_equal_fast_path(struct bs_cache_key *k1,
+ struct bs_cache_key *k2) {
+ if (k1->version == k2->version &&
+ k1->ruby_platform == k2->ruby_platform &&
+ k1->compile_option == k2->compile_option &&
+ k1->ruby_revision == k2->ruby_revision && k1->size == k2->size) {
+ if (k1->mtime == k2->mtime) {
+ return hit;
+ }
+ if (revalidation) {
+ return stale;
+ }
+ }
+ return miss;
+}
+
+static int cache_key_equal_slow_path(struct bs_cache_key *current_key,
+ struct bs_cache_key *cached_key,
+ const VALUE input_data)
+{
+ bs_cache_key_digest(current_key, input_data);
+ return current_key->digest == cached_key->digest;
+}
+
+static int update_cache_key(struct bs_cache_key *current_key, struct
bs_cache_key *old_key, int cache_fd, const char ** errno_provenance)
{
- return (
- k1->version == k2->version &&
- k1->ruby_platform == k2->ruby_platform &&
- k1->compile_option == k2->compile_option &&
- k1->ruby_revision == k2->ruby_revision &&
- k1->size == k2->size &&
- k1->mtime == k2->mtime
- );
+ old_key->mtime = current_key->mtime;
+ lseek(cache_fd, 0, SEEK_SET);
+ ssize_t nwrite = write(cache_fd, old_key, KEY_SIZE);
+ if (nwrite < 0) {
+ *errno_provenance = "update_cache_key:write";
+ return -1;
+ }
+
+#ifdef HAVE_FDATASYNC
+ if (fdatasync(cache_fd) < 0) {
+ *errno_provenance = "update_cache_key:fdatasync";
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
+/*
+ * Fills the cache key digest.
+ */
+static void bs_cache_key_digest(struct bs_cache_key *key,
+ const VALUE input_data) {
+ if (key->digest_set)
+ return;
+ key->digest = fnv1a_64(input_data);
+ key->digest_set = 1;
}
/*
@@ -356,17 +437,34 @@
return bs_precompile(path, path_v, cache_path, handler);
}
+
+static int bs_open_noatime(const char *path, int flags) {
+ int fd = 1;
+ if (!perm_issue) {
+ fd = open(path, flags | O_NOATIME);
+ if (fd < 0 && errno == EPERM) {
+ errno = 0;
+ perm_issue = true;
+ }
+ }
+
+ if (perm_issue) {
+ fd = open(path, flags);
+ }
+ return fd;
+}
+
/*
* Open the file we want to load/cache and generate a cache key for it if it
* was loaded.
*/
static int
-open_current_file(char * path, struct bs_cache_key * key, const char **
errno_provenance)
+open_current_file(const char * path, struct bs_cache_key * key, const char **
errno_provenance)
{
struct stat statbuf;
int fd;
- fd = open(path, O_RDONLY);
+ fd = bs_open_noatime(path, O_RDONLY);
if (fd < 0) {
*errno_provenance = "bs_fetch:open_current_file:open";
return fd;
@@ -389,6 +487,7 @@
key->ruby_revision = current_ruby_revision;
key->size = (uint64_t)statbuf.st_size;
key->mtime = (uint64_t)statbuf.st_mtime;
+ key->digest_set = false;
return fd;
}
@@ -432,7 +531,12 @@
{
int fd, res;
- fd = open(path, O_RDONLY);
+ if (readonly || !revalidation) {
+ fd = bs_open_noatime(path, O_RDONLY);
+ } else {
+ fd = bs_open_noatime(path, O_RDWR);
+ }
+
if (fd < 0) {
*errno_provenance = "bs_fetch:open_cache_file:open";
return CACHE_MISS;
@@ -677,7 +781,8 @@
int res, valid_cache = 0, exception_tag = 0;
const char * errno_provenance = NULL;
- VALUE input_data; /* data read from source file, e.g. YAML or ruby source
*/
+ VALUE status = Qfalse;
+ VALUE input_data = Qfalse; /* data read from source file, e.g. YAML or
ruby source */
VALUE storage_data; /* compiled data, e.g. msgpack / binary iseq */
VALUE output_data; /* return data, e.g. ruby hash or loaded iseq */
@@ -695,20 +800,44 @@
cache_fd = open_cache_file(cache_path, &cached_key, &errno_provenance);
if (cache_fd == CACHE_MISS || cache_fd == CACHE_STALE) {
/* This is ok: valid_cache remains false, we re-populate it. */
- if (RB_UNLIKELY(instrumentation_enabled)) {
- rb_funcall(rb_mBootsnap, instrumentation_method, 2, cache_fd ==
CACHE_MISS ? sym_miss : sym_stale, path_v);
- }
+ bs_instrumentation(cache_fd == CACHE_MISS ? sym_miss : sym_stale, path_v);
} else if (cache_fd < 0) {
exception_message = rb_str_new_cstr(cache_path);
goto fail_errno;
} else {
/* True if the cache existed and no invalidating changes have occurred
since
* it was generated. */
- valid_cache = cache_key_equal(¤t_key, &cached_key);
- if (RB_UNLIKELY(instrumentation_enabled)) {
- if (!valid_cache) {
- rb_funcall(rb_mBootsnap, instrumentation_method, 2, sym_stale, path_v);
+
+ switch(cache_key_equal_fast_path(¤t_key, &cached_key)) {
+ case hit:
+ status = sym_hit;
+ valid_cache = true;
+ break;
+ case miss:
+ valid_cache = false;
+ break;
+ case stale:
+ valid_cache = false;
+ if ((input_data = bs_read_contents(current_fd, current_key.size,
+ &errno_provenance)) == Qfalse) {
+ exception_message = path_v;
+ goto fail_errno;
+ }
+ valid_cache = cache_key_equal_slow_path(¤t_key, &cached_key,
input_data);
+ if (valid_cache) {
+ if (!readonly) {
+ if (update_cache_key(¤t_key, &cached_key, cache_fd,
&errno_provenance)) {
+ exception_message = path_v;
+ goto fail_errno;
+ }
+ }
+ status = sym_revalidated;
}
+ break;
+ };
+
+ if (!valid_cache) {
+ status = sym_stale;
}
}
@@ -722,7 +851,7 @@
else if (res == CACHE_UNCOMPILABLE) {
/* If fetch_cached_data returned `Uncompilable` we fallback to
`input_to_output`
This happens if we have say, an unsafe YAML cache, but try to load it
in safe mode */
- if ((input_data = bs_read_contents(current_fd, current_key.size,
&errno_provenance)) == Qfalse){
+ if (input_data == Qfalse && (input_data = bs_read_contents(current_fd,
current_key.size, &errno_provenance)) == Qfalse) {
exception_message = path_v;
goto fail_errno;
}
@@ -741,7 +870,7 @@
/* Cache is stale, invalid, or missing. Regenerate and write it out. */
/* Read the contents of the source file into a buffer */
- if ((input_data = bs_read_contents(current_fd, current_key.size,
&errno_provenance)) == Qfalse){
+ if (input_data == Qfalse && (input_data = bs_read_contents(current_fd,
current_key.size, &errno_provenance)) == Qfalse) {
exception_message = path_v;
goto fail_errno;
}
@@ -763,6 +892,7 @@
* We do however ignore any failures to persist the cache, as it's better
* to move along, than to interrupt the process.
*/
+ bs_cache_key_digest(¤t_key, input_data);
atomic_write_cache_file(cache_path, ¤t_key, storage_data,
&errno_provenance);
/* Having written the cache, now convert storage_data to output_data */
@@ -792,6 +922,7 @@
goto succeed; /* output_data is now the correct return. */
#define CLEANUP \
+ if (status != Qfalse) bs_instrumentation(status, path_v); \
if (current_fd >= 0) close(current_fd); \
if (cache_fd >= 0) close(cache_fd);
@@ -800,6 +931,12 @@
return output_data;
fail_errno:
CLEANUP;
+ if (errno_provenance) {
+ exception_message = rb_str_concat(
+ rb_str_new_cstr(errno_provenance),
+ rb_str_concat(rb_str_new_cstr(": "), exception_message)
+ );
+ }
exception = rb_syserr_new_str(errno, exception_message);
rb_exc_raise(exception);
__builtin_unreachable();
@@ -818,13 +955,16 @@
static VALUE
bs_precompile(char * path, VALUE path_v, char * cache_path, VALUE handler)
{
+ if (readonly) {
+ return Qfalse;
+ }
+
struct bs_cache_key cached_key, current_key;
- char * contents = NULL;
int cache_fd = -1, current_fd = -1;
int res, valid_cache = 0, exception_tag = 0;
const char * errno_provenance = NULL;
- VALUE input_data; /* data read from source file, e.g. YAML or ruby source
*/
+ VALUE input_data = Qfalse; /* data read from source file, e.g. YAML or
ruby source */
VALUE storage_data; /* compiled data, e.g. msgpack / binary iseq */
/* Open the source file and generate a cache key for it */
@@ -840,7 +980,26 @@
} else {
/* True if the cache existed and no invalidating changes have occurred
since
* it was generated. */
- valid_cache = cache_key_equal(¤t_key, &cached_key);
+ switch(cache_key_equal_fast_path(¤t_key, &cached_key)) {
+ case hit:
+ valid_cache = true;
+ break;
+ case miss:
+ valid_cache = false;
+ break;
+ case stale:
+ valid_cache = false;
+ if ((input_data = bs_read_contents(current_fd, current_key.size,
&errno_provenance)) == Qfalse) {
+ goto fail;
+ }
+ valid_cache = cache_key_equal_slow_path(¤t_key, &cached_key,
input_data);
+ if (valid_cache) {
+ if (update_cache_key(¤t_key, &cached_key, cache_fd,
&errno_provenance)) {
+ goto fail;
+ }
+ }
+ break;
+ };
}
if (valid_cache) {
@@ -867,6 +1026,7 @@
if (!RB_TYPE_P(storage_data, T_STRING)) goto fail;
/* Write the cache key and storage_data to the cache directory */
+ bs_cache_key_digest(¤t_key, input_data);
res = atomic_write_cache_file(cache_path, ¤t_key, storage_data,
&errno_provenance);
if (res < 0) goto fail;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ext/bootsnap/extconf.rb new/ext/bootsnap/extconf.rb
--- old/ext/bootsnap/extconf.rb 2024-01-12 12:03:46.000000000 +0100
+++ new/ext/bootsnap/extconf.rb 2024-01-31 15:42:25.000000000 +0100
@@ -3,21 +3,28 @@
require "mkmf"
if %w[ruby truffleruby].include?(RUBY_ENGINE)
- $CFLAGS << " -O3 "
- $CFLAGS << " -std=c99"
+ have_func "fdatasync", "unistd.h"
+
+ unless RUBY_PLATFORM.match?(/mswin|mingw|cygwin/)
+ append_cppflags ["-D_GNU_SOURCE"] # Needed of O_NOATIME
+ end
+
+ append_cflags ["-O3", "-std=c99"]
# ruby.h has some -Wpedantic fails in some cases
# (e.g. https://github.com/Shopify/bootsnap/issues/15)
unless ["0", "", nil].include?(ENV["BOOTSNAP_PEDANTIC"])
- $CFLAGS << " -Wall"
- $CFLAGS << " -Werror"
- $CFLAGS << " -Wextra"
- $CFLAGS << " -Wpedantic"
-
- $CFLAGS << " -Wno-unused-parameter" # VALUE self has to be there but we
don't care what it is.
- $CFLAGS << " -Wno-keyword-macro" # hiding return
- $CFLAGS << " -Wno-gcc-compat" # ruby.h 2.6.0 on macos 10.14, dunno
- $CFLAGS << " -Wno-compound-token-split-by-macro"
+ append_cflags([
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ "-Wpedantic",
+
+ "-Wno-unused-parameter", # VALUE self has to be there but we don't care
what it is.
+ "-Wno-keyword-macro", # hiding return
+ "-Wno-gcc-compat", # ruby.h 2.6.0 on macos 10.14, dunno
+ "-Wno-compound-token-split-by-macro",
+ ])
end
create_makefile("bootsnap/bootsnap")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/bootsnap/cli.rb new/lib/bootsnap/cli.rb
--- old/lib/bootsnap/cli.rb 2024-01-12 12:03:46.000000000 +0100
+++ new/lib/bootsnap/cli.rb 2024-01-31 15:42:25.000000000 +0100
@@ -60,14 +60,16 @@
precompile_json_files(main_sources)
if compile_gemfile
- # Some gems embed their tests, they're very unlikely to be loaded,
so not worth precompiling.
- gem_exclude = Regexp.union([exclude, "/spec/", "/test/"].compact)
- precompile_ruby_files($LOAD_PATH.map { |d| File.expand_path(d) },
exclude: gem_exclude)
-
# Gems that include JSON or YAML files usually don't put them in
`lib/`.
# So we look at the gem root.
+ # Similarly, gems that include Rails engines generally file Ruby
files in `app/`.
+ # However some gems embed their tests, they're very unlikely to be
loaded, so not worth precompiling.
+ gem_exclude = Regexp.union([exclude, "/spec/", "/test/",
"/features/"].compact)
+
gem_pattern =
%r{^#{Regexp.escape(Bundler.bundle_path.to_s)}/?(?:bundler/)?gems/[^/]+}
- gem_paths = $LOAD_PATH.map { |p| p[gem_pattern] }.compact.uniq
+ gem_paths = $LOAD_PATH.map { |p| p[gem_pattern] || p }.uniq
+
+ precompile_ruby_files(gem_paths, exclude: gem_exclude)
precompile_yaml_files(gem_paths, exclude: gem_exclude)
precompile_json_files(gem_paths, exclude: gem_exclude)
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/bootsnap/compile_cache.rb
new/lib/bootsnap/compile_cache.rb
--- old/lib/bootsnap/compile_cache.rb 2024-01-12 12:03:46.000000000 +0100
+++ new/lib/bootsnap/compile_cache.rb 2024-01-31 15:42:25.000000000 +0100
@@ -9,7 +9,7 @@
Error = Class.new(StandardError)
- def self.setup(cache_dir:, iseq:, yaml:, json:, readonly: false)
+ def self.setup(cache_dir:, iseq:, yaml:, json:, readonly: false,
revalidation: false)
if iseq
if supported?
require_relative "compile_cache/iseq"
@@ -39,6 +39,7 @@
if supported? && defined?(Bootsnap::CompileCache::Native)
Bootsnap::CompileCache::Native.readonly = readonly
+ Bootsnap::CompileCache::Native.revalidation = revalidation
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/bootsnap/version.rb new/lib/bootsnap/version.rb
--- old/lib/bootsnap/version.rb 2024-01-12 12:03:46.000000000 +0100
+++ new/lib/bootsnap/version.rb 2024-01-31 15:42:25.000000000 +0100
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module Bootsnap
- VERSION = "1.17.1"
+ VERSION = "1.18.3"
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/bootsnap.rb new/lib/bootsnap.rb
--- old/lib/bootsnap.rb 2024-01-12 12:03:46.000000000 +0100
+++ new/lib/bootsnap.rb 2024-01-31 15:42:25.000000000 +0100
@@ -11,6 +11,16 @@
class << self
attr_reader :logger
+ def log_stats!
+ stats = {hit: 0, revalidated: 0, miss: 0, stale: 0}
+ self.instrumentation = ->(event, _path) { stats[event] += 1 }
+ Kernel.at_exit do
+ stats.each do |event, count|
+ $stderr.puts "bootsnap #{event}: #{count}"
+ end
+ end
+ end
+
def log!
self.logger = $stderr.method(:puts)
end
@@ -18,9 +28,9 @@
def logger=(logger)
@logger = logger
self.instrumentation = if logger.respond_to?(:debug)
- ->(event, path) { @logger.debug("[Bootsnap] #{event} #{path}") }
+ ->(event, path) { @logger.debug("[Bootsnap] #{event} #{path}") unless
event == :hit }
else
- ->(event, path) { @logger.call("[Bootsnap] #{event} #{path}") }
+ ->(event, path) { @logger.call("[Bootsnap] #{event} #{path}") unless
event == :hit }
end
end
@@ -41,6 +51,7 @@
load_path_cache: true,
ignore_directories: nil,
readonly: false,
+ revalidation: false,
compile_cache_iseq: true,
compile_cache_yaml: true,
compile_cache_json: true
@@ -60,6 +71,7 @@
yaml: compile_cache_yaml,
json: compile_cache_json,
readonly: readonly,
+ revalidation: revalidation,
)
end
@@ -110,6 +122,8 @@
if ENV["BOOTSNAP_LOG"]
log!
+ elsif ENV["BOOTSNAP_STATS"]
+ log_stats!
end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata 2024-01-12 12:03:46.000000000 +0100
+++ new/metadata 2024-01-31 15:42:25.000000000 +0100
@@ -1,14 +1,14 @@
--- !ruby/object:Gem::Specification
name: bootsnap
version: !ruby/object:Gem::Version
- version: 1.17.1
+ version: 1.18.3
platform: ruby
authors:
- Burke Libbey
autorequire:
bindir: exe
cert_chain: []
-date: 2024-01-12 00:00:00.000000000 Z
+date: 2024-01-31 00:00:00.000000000 Z
dependencies:
- !ruby/object:Gem::Dependency
name: msgpack
@@ -83,7 +83,7 @@
- !ruby/object:Gem::Version
version: '0'
requirements: []
-rubygems_version: 3.5.4
+rubygems_version: 3.5.5
signing_key:
specification_version: 4
summary: Boot large ruby/rails apps faster