bitfab 0.57.0 → 0.57.2
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 +4 -4
- data/lib/bitfab/replay_memory.rb +35 -3
- data/lib/bitfab/replay_registry.rb +10 -2
- data/lib/bitfab/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '054905de819e592d260f623159ed33c50c6062e24a35f28005940005c45c8652'
|
|
4
|
+
data.tar.gz: fbf28893c51b904efc74fc2d880d375df4c2d8cd6af46b2421d554083e706a87
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0d5dfb24ef74d933781ad9b6f8d445583dceffcfe0eaf5189b9ba2ec2405b5ef4b108ed828ea8fbb42c66f3bd3e82d171f88d873bb77ae99640185fcbbacf01c
|
|
7
|
+
data.tar.gz: f5509659a2e3f8d8df265d3abba09b106f6553bce8b7d1d9c4227d43c10f58ad74b01400f102e6140d2b37d6a8f518217a11a5914269b7a1a1de779489e0bcf0
|
data/lib/bitfab/replay_memory.rb
CHANGED
|
@@ -5,8 +5,23 @@ require "open3"
|
|
|
5
5
|
module Bitfab
|
|
6
6
|
class ReplayMemoryThrottle
|
|
7
7
|
MIB = 1024 * 1024
|
|
8
|
+
MAX_SWAP_USED_RATIO = 0.85
|
|
9
|
+
CRITICAL_PRESSURE_LEVEL = 4
|
|
10
|
+
CRITICAL_STALL_PERCENT = 10.0
|
|
11
|
+
STALL_FILES = ["/sys/fs/cgroup/memory.pressure", "/proc/pressure/memory"].freeze
|
|
8
12
|
attr_reader :condition
|
|
9
13
|
|
|
14
|
+
def self.pressure_critical_from_level(raw)
|
|
15
|
+
level = Integer(raw.to_s.strip, exception: false)
|
|
16
|
+
return nil unless level&.positive?
|
|
17
|
+
level >= CRITICAL_PRESSURE_LEVEL
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.pressure_critical_from_stall(raw)
|
|
21
|
+
percent = raw.to_s[/^full\b[^\n]*?\bavg10=([\d.]+)/, 1]
|
|
22
|
+
percent && percent.to_f >= CRITICAL_STALL_PERCENT
|
|
23
|
+
end
|
|
24
|
+
|
|
10
25
|
def initialize(enabled: true)
|
|
11
26
|
@enabled = enabled && !%w[0 off false no].include?(ENV.fetch("BITFAB_REPLAY_MEMORY_THROTTLE", "").strip.downcase)
|
|
12
27
|
@initial_budget = env_bytes("BITFAB_REPLAY_CHILD_MEMORY_MB", 2048 * MIB)
|
|
@@ -50,7 +65,7 @@ module Bitfab
|
|
|
50
65
|
def headroom?
|
|
51
66
|
return true if @resident.empty?
|
|
52
67
|
snapshot = memory_snapshot
|
|
53
|
-
return false if snapshot
|
|
68
|
+
return false if under_strain?(snapshot)
|
|
54
69
|
return true unless snapshot[:available]
|
|
55
70
|
budget = [@peak.positive? ? @peak : @initial_budget, *@resident.values].max
|
|
56
71
|
unrealized = @resident.values.sum { |rss| [budget - rss, 0].max }
|
|
@@ -61,14 +76,15 @@ module Bitfab
|
|
|
61
76
|
if File.file?("/proc/meminfo")
|
|
62
77
|
fields = File.read("/proc/meminfo").scan(/^(\w+):\s+(\d+)/).to_h.transform_values { |value| value.to_i * 1024 }
|
|
63
78
|
total = fields["SwapTotal"].to_i
|
|
64
|
-
{available: fields["MemAvailable"], swap_used_ratio: total.positive? ? 1.0 - fields["SwapFree"].to_f / total : 0.0}
|
|
79
|
+
{available: fields["MemAvailable"], swap_used_ratio: total.positive? ? 1.0 - fields["SwapFree"].to_f / total : 0.0, pressure_critical: stall_files_pressure_critical}
|
|
65
80
|
elsif RUBY_PLATFORM.include?("darwin")
|
|
66
81
|
total = Integer(read_command("sysctl", "-n", "hw.memsize").to_s, exception: false)
|
|
67
82
|
percent = Integer(read_command("sysctl", "-n", "kern.memorystatus_level").to_s, exception: false)
|
|
68
83
|
swap = read_command("sysctl", "-n", "vm.swapusage").to_s
|
|
69
84
|
total_swap = swap[/total = ([\d.]+)/, 1].to_f
|
|
70
85
|
used_swap = swap[/used = ([\d.]+)/, 1].to_f
|
|
71
|
-
|
|
86
|
+
pressure = self.class.pressure_critical_from_level(read_command("sysctl", "-n", "kern.memorystatus_vm_pressure_level"))
|
|
87
|
+
{available: (percent && total&.positive?) ? total * percent.to_i.clamp(0, 100) / 100 : nil, swap_used_ratio: total_swap.positive? ? used_swap / total_swap : 0.0, pressure_critical: pressure}
|
|
72
88
|
else
|
|
73
89
|
{}
|
|
74
90
|
end
|
|
@@ -89,6 +105,22 @@ module Bitfab
|
|
|
89
105
|
|
|
90
106
|
private
|
|
91
107
|
|
|
108
|
+
def under_strain?(snapshot)
|
|
109
|
+
return snapshot[:pressure_critical] unless snapshot[:pressure_critical].nil?
|
|
110
|
+
!!(snapshot[:swap_used_ratio] && snapshot[:swap_used_ratio] >= MAX_SWAP_USED_RATIO)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def stall_files_pressure_critical
|
|
114
|
+
STALL_FILES.each do |path|
|
|
115
|
+
next unless File.file?(path)
|
|
116
|
+
critical = self.class.pressure_critical_from_stall(File.read(path))
|
|
117
|
+
return critical unless critical.nil?
|
|
118
|
+
end
|
|
119
|
+
nil
|
|
120
|
+
rescue
|
|
121
|
+
nil
|
|
122
|
+
end
|
|
123
|
+
|
|
92
124
|
def env_bytes(key, fallback)
|
|
93
125
|
value = Integer(ENV.fetch(key, "0"), exception: false)
|
|
94
126
|
value&.positive? ? value * MIB : fallback
|
|
@@ -91,6 +91,14 @@ module Bitfab
|
|
|
91
91
|
|
|
92
92
|
module_function
|
|
93
93
|
|
|
94
|
+
# get_assertions returns every state so a reviewer can see drafts, but only an
|
|
95
|
+
# approved assertion is checked on a replay, so narrowing on anything else
|
|
96
|
+
# would pick traces the run cannot be judged against. The server applies the
|
|
97
|
+
# same rule when it revalidates the selection.
|
|
98
|
+
def approved_assertion?(assertions)
|
|
99
|
+
assertions.any? { |assertion| assertion["approvalState"] == "approved" }
|
|
100
|
+
end
|
|
101
|
+
|
|
94
102
|
def bound_trace_ids(client, trace_ids, limit, only_with_assertions)
|
|
95
103
|
unless limit.is_a?(Integer) && limit.positive?
|
|
96
104
|
raise ArgumentError, "Replay limit must be a positive integer."
|
|
@@ -100,13 +108,13 @@ module Bitfab
|
|
|
100
108
|
selected = []
|
|
101
109
|
trace_ids.each do |trace_id|
|
|
102
110
|
result = client.traces.get_assertions(trace_id)
|
|
103
|
-
if result.fetch("inheritedFrom").nil? &&
|
|
111
|
+
if result.fetch("inheritedFrom").nil? && approved_assertion?(result.fetch("assertions"))
|
|
104
112
|
selected << trace_id
|
|
105
113
|
break if selected.length == limit
|
|
106
114
|
end
|
|
107
115
|
end
|
|
108
116
|
if selected.empty?
|
|
109
|
-
raise ArgumentError, "No traces with
|
|
117
|
+
raise ArgumentError, "No traces with approved assertions matched this replay selection."
|
|
110
118
|
end
|
|
111
119
|
selected
|
|
112
120
|
end
|
data/lib/bitfab/version.rb
CHANGED