@@ -15,6 +15,9 @@ use std::{
1515 thread:: JoinHandle ,
1616} ;
1717
18+ const LOG_TAG : & str = "Pyroscope::Pyspy" ;
19+
20+ /// Short-hand function for creating a new Pyspy backend.
1821pub fn pyspy_backend ( config : PyspyConfig ) -> BackendImpl < BackendUninitialized > {
1922 BackendImpl :: new ( Box :: new ( Pyspy :: new ( config) ) )
2023}
@@ -140,7 +143,7 @@ impl std::fmt::Debug for Pyspy {
140143}
141144
142145impl Pyspy {
143- /// Create a new Pyspy Backend
146+ /// Create a new Pyspy Backend.
144147 pub fn new ( config : PyspyConfig ) -> Self {
145148 Pyspy {
146149 buffer : Arc :: new ( Mutex :: new ( StackBuffer :: default ( ) ) ) ,
@@ -154,26 +157,31 @@ impl Pyspy {
154157}
155158
156159impl Backend for Pyspy {
160+ /// Return the name of the backend.
157161 fn spy_name ( & self ) -> Result < String > {
158162 Ok ( "pyspy" . to_string ( ) )
159163 }
160164
165+ /// Return the sample rate.
161166 fn sample_rate ( & self ) -> Result < u32 > {
162167 Ok ( self . config . sample_rate )
163168 }
164169
170+ /// Add a rule to the ruleset.
165171 fn add_rule ( & self , rule : Rule ) -> Result < ( ) > {
166172 self . ruleset . lock ( ) ?. add_rule ( rule) ?;
167173
168174 Ok ( ( ) )
169175 }
170176
177+ /// Remove a rule from the ruleset.
171178 fn remove_rule ( & self , rule : Rule ) -> Result < ( ) > {
172179 self . ruleset . lock ( ) ?. remove_rule ( rule) ?;
173180
174181 Ok ( ( ) )
175182 }
176183
184+ /// Initialize the backend.
177185 fn initialize ( & mut self ) -> Result < ( ) > {
178186 // Check if a process ID is set
179187 if self . config . pid . is_none ( ) {
@@ -200,9 +208,6 @@ impl Backend for Pyspy {
200208 ..Config :: default ( )
201209 } ) ;
202210
203- //
204- //
205- //
206211 // set sampler state to running
207212 let running = Arc :: clone ( & self . running ) ;
208213 running. store ( true , Ordering :: Relaxed ) ;
@@ -216,11 +221,11 @@ impl Backend for Pyspy {
216221 . clone ( )
217222 . ok_or_else ( || PyroscopeError :: new ( "Pyspy: Sampler configuration is not set" ) ) ?;
218223
224+ // create a new ruleset reference
219225 let ruleset = self . ruleset . clone ( ) ;
220226
221227 self . sampler_thread = Some ( std:: thread:: spawn ( move || {
222228 // Get PID
223- // TODO: we are doing lots of these checks, we should probably do this once
224229 let pid = config
225230 . pid
226231 . ok_or_else ( || PyroscopeError :: new ( "Pyspy: PID is not set" ) ) ?;
@@ -235,10 +240,12 @@ impl Backend for Pyspy {
235240 // Collect the sampler output
236241 for sample in sampler_output {
237242 for trace in sample. traces {
243+ // idle config
238244 if !( config. include_idle || trace. active ) {
239245 continue ;
240246 }
241247
248+ // gil config
242249 if config. gil_only && !trace. owns_gil {
243250 continue ;
244251 }
@@ -261,35 +268,37 @@ impl Backend for Pyspy {
261268 Ok ( ( ) )
262269 }
263270
271+ /// Shutdown the backend.
264272 fn shutdown ( self : Box < Self > ) -> Result < ( ) > {
265- // set running to false
266- //self.running.store(false, Ordering::Relaxed);
273+ log:: trace!( target: LOG_TAG , "Shutting down sampler thread" ) ;
274+
275+ // set running to false, terminate sampler thread
276+ self . running . store ( false , Ordering :: Relaxed ) ;
267277
268278 // wait for sampler thread to finish
269279 self . sampler_thread
270- //.take()
271280 . ok_or_else ( || PyroscopeError :: new ( "Pyspy: Failed to unwrap Sampler Thread" ) ) ?
272281 . join ( )
273282 . unwrap_or_else ( |_| Err ( PyroscopeError :: new ( "Pyspy: Failed to join sampler thread" ) ) ) ?;
274283
275284 Ok ( ( ) )
276285 }
277286
287+ /// Report buffer
278288 fn report ( & mut self ) -> Result < Vec < Report > > {
279- // create a new buffer reference
280- let buffer = self . buffer . clone ( ) ;
281-
282289 // convert the buffer report into a byte vector
283- let report: StackBuffer = buffer. lock ( ) ?. deref ( ) . to_owned ( ) ;
290+ let report: StackBuffer = self . buffer . lock ( ) ?. deref ( ) . to_owned ( ) ;
284291 let reports: Vec < Report > = report. into ( ) ;
285292
286293 // Clear the buffer
287- buffer. lock ( ) ?. clear ( ) ;
294+ self . buffer . lock ( ) ?. clear ( ) ;
288295
289296 Ok ( reports)
290297 }
291298}
292299
300+ /// Wrapper for StackFrame. This is needed because both StackFrame and
301+ /// py_spy::Frame are not defined in the same module.
293302struct StackFrameWrapper ( StackFrame ) ;
294303
295304impl From < StackFrameWrapper > for StackFrame {
@@ -311,6 +320,8 @@ impl From<py_spy::Frame> for StackFrameWrapper {
311320 }
312321}
313322
323+ /// Wrapper for StackTrace. This is needed because both StackTrace and
324+ /// py_spy::StackTrace are not defined in the same module.
314325struct StackTraceWrapper ( StackTrace ) ;
315326
316327impl From < StackTraceWrapper > for StackTrace {
0 commit comments