Skip to content

Commit 91d8408

Browse files
committed
WS3
1 parent 0f43fdf commit 91d8408

File tree

3 files changed

+38
-66
lines changed

3 files changed

+38
-66
lines changed

codetracer-python-recorder/src/runtime/tracer/events.rs

Lines changed: 10 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Event handling pipeline for `RuntimeTracer`.
22
3-
use super::filtering::TraceDecision;
43
use super::runtime_tracer::RuntimeTracer;
54
use crate::code_object::CodeObjectWrapper;
65
use crate::ffi;
@@ -177,18 +176,8 @@ impl Tracer for RuntimeTracer {
177176
code: &CodeObjectWrapper,
178177
_offset: i32,
179178
) -> CallbackResult {
180-
let is_active = self
181-
.lifecycle
182-
.activation_mut()
183-
.should_process_event(py, code);
184-
if matches!(
185-
self.should_trace_code(py, code),
186-
TraceDecision::SkipAndDisable
187-
) {
188-
return Ok(CallbackOutcome::Continue);
189-
}
190-
if !is_active {
191-
return Ok(CallbackOutcome::Continue);
179+
if let Some(outcome) = self.evaluate_gate(py, code, true) {
180+
return Ok(outcome);
192181
}
193182

194183
if should_inject_failure(FailureStage::PyStart) {
@@ -244,18 +233,8 @@ impl Tracer for RuntimeTracer {
244233
code: &CodeObjectWrapper,
245234
_offset: i32,
246235
) -> CallbackResult {
247-
let is_active = self
248-
.lifecycle
249-
.activation_mut()
250-
.should_process_event(py, code);
251-
if matches!(
252-
self.should_trace_code(py, code),
253-
TraceDecision::SkipAndDisable
254-
) {
255-
return Ok(CallbackOutcome::Continue);
256-
}
257-
if !is_active {
258-
return Ok(CallbackOutcome::Continue);
236+
if let Some(outcome) = self.evaluate_gate(py, code, false) {
237+
return Ok(outcome);
259238
}
260239

261240
log_event(py, code, "on_py_resume", None);
@@ -264,18 +243,8 @@ impl Tracer for RuntimeTracer {
264243
}
265244

266245
fn on_line(&mut self, py: Python<'_>, code: &CodeObjectWrapper, lineno: u32) -> CallbackResult {
267-
let is_active = self
268-
.lifecycle
269-
.activation_mut()
270-
.should_process_event(py, code);
271-
if matches!(
272-
self.should_trace_code(py, code),
273-
TraceDecision::SkipAndDisable
274-
) {
275-
return Ok(CallbackOutcome::Continue);
276-
}
277-
if !is_active {
278-
return Ok(CallbackOutcome::Continue);
246+
if let Some(outcome) = self.evaluate_gate(py, code, false) {
247+
return Ok(outcome);
279248
}
280249

281250
if should_inject_failure(FailureStage::Line) {
@@ -378,18 +347,8 @@ impl Tracer for RuntimeTracer {
378347
_offset: i32,
379348
exception: &Bound<'_, PyAny>,
380349
) -> CallbackResult {
381-
let is_active = self
382-
.lifecycle
383-
.activation_mut()
384-
.should_process_event(py, code);
385-
if matches!(
386-
self.should_trace_code(py, code),
387-
TraceDecision::SkipAndDisable
388-
) {
389-
return Ok(CallbackOutcome::Continue);
390-
}
391-
if !is_active {
392-
return Ok(CallbackOutcome::Continue);
350+
if let Some(outcome) = self.evaluate_gate(py, code, false) {
351+
return Ok(outcome);
393352
}
394353

395354
log_event(py, code, "on_py_throw", None);
@@ -564,22 +523,8 @@ impl RuntimeTracer {
564523
exit_kind: Option<ActivationExitKind>,
565524
allow_disable: bool,
566525
) -> CallbackResult {
567-
let is_active = self
568-
.lifecycle
569-
.activation_mut()
570-
.should_process_event(py, code);
571-
if matches!(
572-
self.should_trace_code(py, code),
573-
TraceDecision::SkipAndDisable
574-
) {
575-
return Ok(if allow_disable {
576-
CallbackOutcome::DisableLocation
577-
} else {
578-
CallbackOutcome::Continue
579-
});
580-
}
581-
if !is_active {
582-
return Ok(CallbackOutcome::Continue);
526+
if let Some(outcome) = self.evaluate_gate(py, code, allow_disable) {
527+
return Ok(outcome);
583528
}
584529

585530
log_event(py, code, label, None);

codetracer-python-recorder/src/runtime/tracer/runtime_tracer.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use super::lifecycle::LifecycleController;
55
use crate::code_object::CodeObjectWrapper;
66
use crate::ffi;
77
use crate::module_identity::{ModuleIdentityCache, ModuleNameHints};
8+
use crate::monitoring::CallbackOutcome;
89
use crate::policy::RecorderPolicy;
910
use crate::runtime::io_capture::{IoCaptureSettings, ScopedMuteIoCapture};
1011
use crate::runtime::line_snapshots::LineSnapshotStore;
@@ -201,6 +202,29 @@ impl RuntimeTracer {
201202
self.session_exit.set_exit_code(exit_code);
202203
}
203204

205+
pub(super) fn evaluate_gate(
206+
&mut self,
207+
py: Python<'_>,
208+
code: &CodeObjectWrapper,
209+
allow_disable: bool,
210+
) -> Option<CallbackOutcome> {
211+
let is_active = self.lifecycle.activation_mut().should_process_event(py, code);
212+
if matches!(
213+
self.should_trace_code(py, code),
214+
TraceDecision::SkipAndDisable
215+
) {
216+
return Some(if allow_disable {
217+
CallbackOutcome::DisableLocation
218+
} else {
219+
CallbackOutcome::Continue
220+
});
221+
}
222+
if !is_active {
223+
return Some(CallbackOutcome::Continue);
224+
}
225+
None
226+
}
227+
204228
pub(super) fn ensure_function_id(
205229
&mut self,
206230
py: Python<'_>,

design-docs/toplevel-exit-and-trace-gating-implementation-plan.status.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@
2828
- Verification: `just cargo-test` (workspace) and `just py-test` exercises the new Rust test (`finish_emits_toplevel_return_with_exit_code`) and Python integration tests (`test_exit_payloads`).
2929

3030
### WS3 – Unified Trace Gate Abstraction
31-
- **Status:** _Not Started_.
31+
- **Status:** _Completed_
32+
- Added a single `evaluate_gate` helper so callbacks defer to shared activation+filter logic, ensuring consistent disable decisions and reducing duplicated guards.
33+
- All tracer callbacks now consult the helper; return handlers pass through the same decision pipeline before emitting events.
34+
- Verification: `just cargo-test` and `just py-test`.
3235

3336
### WS4 – Lifecycle & Metadata Updates
3437
- **Status:** _Not Started_.

0 commit comments

Comments
 (0)