Skip to content

Commit ce27de4

Browse files
committed
Only prevent backend switch/clear when AppProfiler is active
running? can be true if the backend is busy due to another caller; that needn't prevent AppProfiler from changing state.
1 parent 2ccab07 commit ce27de4

4 files changed

Lines changed: 46 additions & 2 deletions

File tree

lib/app_profiler.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def profiler
127127
def backend=(new_backend)
128128
return if (new_profiler_backend = backend_for(new_backend)) == profiler_backend
129129

130-
if running?
130+
if profiler_backend.locked?
131131
raise BackendError,
132132
"cannot change backend to #{new_backend} while #{backend} backend is running"
133133
end
@@ -269,7 +269,7 @@ def profiler_backend
269269
end
270270

271271
def clear
272-
profiler.stop if running?
272+
profiler.stop if profiler_backend.locked?
273273
@profiler = nil
274274
@profiler_backend = nil
275275
end

lib/app_profiler/backend/base_backend.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ def run_lock
4747
@run_lock ||= Mutex.new
4848
end
4949

50+
def locked?
51+
run_lock.locked?
52+
end
53+
5054
def name
5155
raise NotImplementedError
5256
end

test/app_profiler/backend_test.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,24 @@ class BackendTest < TestCase
2727
AppProfiler.backend = orig_backend
2828
end
2929

30+
test ".backend= updates the backend while a foreign StackProf session is active" do
31+
orig_backend = AppProfiler.backend
32+
skip("Vernier not supported") unless AppProfiler.vernier_supported?
33+
AppProfiler.backend = AppProfiler::Backend::StackprofBackend.name
34+
AppProfiler.profiler # force @profiler memoization so AppProfiler.running? actually delegates
35+
36+
StackProf.start(mode: :wall, interval: 1000)
37+
begin
38+
AppProfiler.backend = AppProfiler::VernierProfile::BACKEND_NAME
39+
assert_equal(AppProfiler::VernierProfile::BACKEND_NAME, AppProfiler.backend)
40+
ensure
41+
StackProf.stop
42+
StackProf.results
43+
end
44+
ensure
45+
AppProfiler.backend = orig_backend
46+
end
47+
3048
test ".backend= accepts a symbol with the backend name" do
3149
orig_backend = AppProfiler.backend
3250
skip("Vernier not supported") unless AppProfiler.vernier_supported?

test/app_profiler/run_test.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,27 @@ class RunTest < TestCase
5959
ensure
6060
AppProfiler.backend = orig_backend
6161
end
62+
63+
test ".run swaps backend even while a foreign StackProf session is active" do
64+
orig_backend = AppProfiler.backend
65+
skip("Vernier not supported") unless AppProfiler.vernier_supported?
66+
AppProfiler.backend = AppProfiler::Backend::StackprofBackend.name
67+
AppProfiler.profiler # force @profiler memoization so AppProfiler.running? actually delegates
68+
69+
StackProf.start(mode: :wall, interval: 1000)
70+
begin
71+
profile = AppProfiler.run(backend: AppProfiler::VernierProfile::BACKEND_NAME) do
72+
sleep(0.01)
73+
end
74+
75+
assert_instance_of(AppProfiler::VernierProfile, profile)
76+
assert_equal(AppProfiler::Backend::StackprofBackend.name, AppProfiler.backend)
77+
ensure
78+
StackProf.stop
79+
StackProf.results
80+
end
81+
ensure
82+
AppProfiler.backend = orig_backend
83+
end
6284
end
6385
end

0 commit comments

Comments
 (0)