Skip to content

Commit e4a9105

Browse files
committed
Start-Agent-Branch: tracer-trait
Target-Remote: https://github.com/metacraft-labs/codetracer-python-recorder.git
1 parent c175f01 commit e4a9105

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
1. Create a trait for a tracer implemented using the Python monitoring API. The methods of the trait should correspond to the events that one can subscribe to via the API.
2+
3+
Here's a sketch of the design of the trait. We want to support tracers which implement only some of the methods.
4+
5+
``rs
6+
use bitflags::bitflags;
7+
8+
bitflags! {
9+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10+
pub struct EventMask: u32 {
11+
const CALL = 1 << 0;
12+
//CODEX: write this
13+
...
14+
}
15+
}
16+
17+
#[non_exhaustive]
18+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19+
pub enum Event {
20+
Call,
21+
//CODEX: write this
22+
...
23+
// Non-exhaustive for forward compatibility.
24+
}
25+
26+
pub trait Tracer: Send {
27+
/// Tell the dispatcher what you want to receive. Default: nothing (fast path).
28+
fn interest(&self) -> EventMask { EventMask::empty() }
29+
30+
// Default no-ops let implementers pick only what they need.
31+
fn on_call(&mut self, ...) {}
32+
//CODEX: write this
33+
}
34+
35+
// Example tracer: only cares about CALL.
36+
struct CallsOnly;
37+
impl Tracer for CallsOnly {
38+
fn interest(&self) -> EventMask { EventMask::CALL | ... }
39+
fn on_call(&mut self, ...) { println!("call: {:?}", ...); }
40+
...
41+
}
42+
43+
// Dispatcher checks the mask to avoid vtable calls it doesn’t need.
44+
pub struct Dispatcher {
45+
tracer: Box<dyn Tracer>,
46+
mask: EventMask,
47+
}
48+
49+
impl Dispatcher {
50+
pub fn new(tracer: Box<dyn Tracer>) -> Self {
51+
let mask = tracer.interest();
52+
Self { tracer, mask }
53+
}
54+
55+
pub fn dispatch_call(&mut self, ...) {
56+
if self.mask.contains(EventMask::CALL) {
57+
self.tracer.on_call(...);
58+
}
59+
60+
}
61+
// CODEX: ... same for other events
62+
}
63+
``
64+
65+
2. Create code which takes a trait implementation and hooks it to the global tracing. Follow the design-docs for the specific API that needs to be implemented.
66+
67+
3. Create a test implementation of the trait which prints text to stdout. Run the test implementation. Note that the test implementation should not be included in the final build
68+
artefact, it will be used only for testing.
69+
70+
4. Update the testing framework to be able to use `just test` also for Rust tests. Specifically we want to run our test implementation from point 2. using `just test`
71+
72+
Refer to the design-docs folder for the current planned design. Add/update files in the folder to match what was implemented in this task.
73+
74+
75+
--- FOLLOW UP TASK ---
76+
1. In codetracer-python-recorder/Cargo.toml, move pyo3’s extension-module feature to an optional crate feature and enable it only for release builds.
77+
2. Update Justfile (and CI scripts) to run cargo test --no-default-features so the test binary links with the Python C library.
78+
3. Add pyo3 with auto-initialize under [dev-dependencies] if tests require the interpreter to be initialized automatically.
79+
--- FOLLOW UP TASK ---
80+
thread 'tracer_prints_on_call' panicked at tests/print_tracer.rs:21:51:\ncalled `Result::unwrap()` on an `Err` value: PyErr { type: <class 'AttributeError'>, value: AttributeError("module 'sys' has no attribute 'monitoring'"), traceback: None }\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n\n\nfailures:\n tracer_prints_on_call\n\ntest result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s

0 commit comments

Comments
 (0)