@@ -137,7 +137,7 @@ def is_gevent():
137
137
138
138
139
139
def setup_profiler (options ):
140
- # type: (Dict[str, Any]) -> None
140
+ # type: (Dict[str, Any]) -> bool
141
141
"""
142
142
`buffer_secs` determines the max time a sample will be buffered for
143
143
`frequency` determines the number of samples to take per second (Hz)
@@ -147,11 +147,11 @@ def setup_profiler(options):
147
147
148
148
if _scheduler is not None :
149
149
logger .debug ("profiling is already setup" )
150
- return
150
+ return False
151
151
152
152
if not PY33 :
153
153
logger .warn ("profiling is only supported on Python >= 3.3" )
154
- return
154
+ return False
155
155
156
156
frequency = 101
157
157
@@ -184,6 +184,8 @@ def setup_profiler(options):
184
184
185
185
atexit .register (teardown_profiler )
186
186
187
+ return True
188
+
187
189
188
190
def teardown_profiler ():
189
191
# type: () -> None
@@ -410,8 +412,7 @@ def __init__(
410
412
#
411
413
# We cannot keep a reference to the transaction around here because it'll create
412
414
# a reference cycle. So we opt to pull out just the necessary attributes.
413
- self ._transaction_sampled = transaction .sampled # type: Optional[bool]
414
- self .sampled = None # type: Optional[bool]
415
+ self .sampled = transaction .sampled # type: Optional[bool]
415
416
416
417
# Various framework integrations are capable of overwriting the active thread id.
417
418
# If it is set to `None` at the end of the profile, we fall back to the default.
@@ -448,7 +449,7 @@ def _set_initial_sampling_decision(self, sampling_context):
448
449
449
450
# The corresponding transaction was not sampled,
450
451
# so don't generate a profile for it.
451
- if not self ._transaction_sampled :
452
+ if not self .sampled :
452
453
self .sampled = False
453
454
return
454
455
@@ -485,19 +486,21 @@ def get_profile_context(self):
485
486
486
487
def start (self ):
487
488
# type: () -> None
488
- if not self .sampled :
489
+ if not self .sampled or self . active :
489
490
return
490
491
491
492
assert self .scheduler , "No scheduler specified"
493
+ self .active = True
492
494
self .start_ns = nanosecond_time ()
493
495
self .scheduler .start_profiling (self )
494
496
495
497
def stop (self ):
496
498
# type: () -> None
497
- if not self .sampled :
499
+ if not self .sampled or not self . active :
498
500
return
499
501
500
502
assert self .scheduler , "No scheduler specified"
503
+ self .active = False
501
504
self .scheduler .stop_profiling (self )
502
505
self .stop_ns = nanosecond_time ()
503
506
@@ -526,11 +529,15 @@ def __exit__(self, ty, value, tb):
526
529
527
530
def write (self , ts , sample ):
528
531
# type: (int, RawSample) -> None
532
+ if not self .active :
533
+ return
534
+
529
535
if ts < self .start_ns :
530
536
return
531
537
532
538
offset = ts - self .start_ns
533
539
if offset > MAX_PROFILE_DURATION_NS :
540
+ self .stop ()
534
541
return
535
542
536
543
elapsed_since_start_ns = str (offset )
@@ -666,12 +673,11 @@ def teardown(self):
666
673
667
674
def start_profiling (self , profile ):
668
675
# type: (Profile) -> None
669
- profile .active = True
670
676
self .new_profiles .append (profile )
671
677
672
678
def stop_profiling (self , profile ):
673
679
# type: (Profile) -> None
674
- profile . active = False
680
+ pass
675
681
676
682
def make_sampler (self ):
677
683
# type: () -> Callable[..., None]
0 commit comments