Skip to content

Commit 7eb03b2

Browse files
committed
Add hit instrumentation events and add log_stat!
1 parent 4a91add commit 7eb03b2

File tree

5 files changed

+27
-17
lines changed

5 files changed

+27
-17
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Unreleased
22

3+
* `Bootsnap.instrumentation` now receive `:hit` events.
4+
* Add `Bootsnap.log_stats!` to print hit rate statistics on process exit. Can also be enabled with `BOOTSNAP_STATS=1`.
35
* Revalidate stale cache entries by digesting the source content.
46
This should significantly improve performance in environments where `mtime` isn't preserved (e.g. CI systems doing a git clone, etc).
57
See #468.

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ well together.
8181
- `DISABLE_BOOTSNAP_COMPILE_CACHE` allows to disable ISeq and YAML caches.
8282
- `BOOTSNAP_READONLY` configure bootsnap to not update the cache on miss or stale entries.
8383
- `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.
8485
- `BOOTSNAP_IGNORE_DIRECTORIES` a comma separated list of directories that shouldn't be scanned.
8586
Useful when you have large directories of non-ruby files inside `$LOAD_PATH`.
8687
It defaults to ignore any directory named `node_modules`.
@@ -99,8 +100,8 @@ Bootsnap cache misses can be monitored though a callback:
99100
Bootsnap.instrumentation = ->(event, path) { puts "#{event} #{path}" }
100101
```
101102

102-
`event` is either `:miss`, `:stale` or `:revalidated`. You can also call `Bootsnap.log!` as a shortcut to
103-
log all events to STDERR.
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.
104105

105106
To turn instrumentation back off you can set it to nil:
106107

ext/bootsnap/bootsnap.c

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ static VALUE rb_mBootsnap_CompileCache;
9393
static VALUE rb_mBootsnap_CompileCache_Native;
9494
static VALUE rb_cBootsnap_CompileCache_UNCOMPILABLE;
9595
static ID instrumentation_method;
96-
static VALUE sym_miss;
97-
static VALUE sym_stale;
98-
static VALUE sym_revalidated;
96+
static VALUE sym_hit, sym_miss, sym_stale, sym_revalidated;
9997
static bool instrumentation_enabled = false;
10098
static bool readonly = false;
10199

@@ -177,14 +175,10 @@ Init_bootsnap(void)
177175

178176
instrumentation_method = rb_intern("_instrument");
179177

178+
sym_hit = ID2SYM(rb_intern("hit"));
180179
sym_miss = ID2SYM(rb_intern("miss"));
181-
rb_global_variable(&sym_miss);
182-
183180
sym_stale = ID2SYM(rb_intern("stale"));
184-
rb_global_variable(&sym_stale);
185-
186181
sym_revalidated = ID2SYM(rb_intern("revalidated"));
187-
rb_global_variable(&sym_revalidated);
188182

189183
rb_define_module_function(rb_mBootsnap, "instrumentation_enabled=", bs_instrumentation_enabled_set, 1);
190184
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "readonly=", bs_readonly_set, 1);
@@ -746,6 +740,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
746740
int res, valid_cache = 0, exception_tag = 0;
747741
const char * errno_provenance = NULL;
748742

743+
VALUE status = Qfalse;
749744
VALUE input_data = Qfalse; /* data read from source file, e.g. YAML or ruby source */
750745
VALUE storage_data; /* compiled data, e.g. msgpack / binary iseq */
751746
VALUE output_data; /* return data, e.g. ruby hash or loaded iseq */
@@ -774,6 +769,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
774769

775770
switch(cache_key_equal_fast_path(&current_key, &cached_key)) {
776771
case hit:
772+
status = sym_hit;
777773
valid_cache = true;
778774
break;
779775
case miss:
@@ -794,13 +790,13 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
794790
goto fail_errno;
795791
}
796792
}
797-
bs_instrumentation(sym_revalidated, path_v);
793+
status = sym_revalidated;
798794
}
799795
break;
800796
};
801797

802798
if (!valid_cache) {
803-
bs_instrumentation(sym_stale, path_v);
799+
status = sym_stale;
804800
}
805801
}
806802

@@ -885,6 +881,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
885881
goto succeed; /* output_data is now the correct return. */
886882

887883
#define CLEANUP \
884+
if (status != Qfalse) bs_instrumentation(status, path_v); \
888885
if (current_fd >= 0) close(current_fd); \
889886
if (cache_fd >= 0) close(cache_fd);
890887

@@ -953,8 +950,6 @@ bs_precompile(char * path, VALUE path_v, char * cache_path, VALUE handler)
953950
if (update_cache_key(&current_key, cache_fd, &errno_provenance)) {
954951
goto fail;
955952
}
956-
957-
bs_instrumentation(sym_revalidated, path_v);
958953
}
959954
break;
960955
};

lib/bootsnap.rb

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,26 @@ module Bootsnap
1111
class << self
1212
attr_reader :logger
1313

14+
def log_stats!
15+
stats = {hit: 0, revalidated: 0, miss: 0, stale: 0}
16+
self.instrumentation = ->(event, _path) { stats[event] += 1 }
17+
Kernel.at_exit do
18+
stats.each do |event, count|
19+
$stderr.puts "bootsnap #{event}: #{count}"
20+
end
21+
end
22+
end
23+
1424
def log!
1525
self.logger = $stderr.method(:puts)
1626
end
1727

1828
def logger=(logger)
1929
@logger = logger
2030
self.instrumentation = if logger.respond_to?(:debug)
21-
->(event, path) { @logger.debug("[Bootsnap] #{event} #{path}") }
31+
->(event, path) { @logger.debug("[Bootsnap] #{event} #{path}") unless event == :hit }
2232
else
23-
->(event, path) { @logger.call("[Bootsnap] #{event} #{path}") }
33+
->(event, path) { @logger.call("[Bootsnap] #{event} #{path}") unless event == :hit }
2434
end
2535
end
2636

@@ -110,6 +120,8 @@ def default_setup
110120

111121
if ENV["BOOTSNAP_LOG"]
112122
log!
123+
elsif ENV["BOOTSNAP_STATS"]
124+
log_stats!
113125
end
114126
end
115127
end

test/compile_cache_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def test_instrumentation_hit
205205

206206
load(file_path)
207207

208-
assert_equal [], calls
208+
assert_equal [[:hit, "a.rb"]], calls
209209
end
210210

211211
def test_instrumentation_miss

0 commit comments

Comments
 (0)