def acquire(self, *args, **kwargs): if not self._self_capture_sampler.capture(): return self.__wrapped__.acquire(*args, **kwargs) start = compat.monotonic_ns() try: return self.__wrapped__.acquire(*args, **kwargs) finally: try: end = self._self_acquired_at = compat.monotonic_ns() thread_id, thread_name = _current_thread() frames, nframes = _traceback.pyframe_to_frames( sys._getframe(1), self._self_max_nframes) trace_id, span_id, trace_resource, trace_type = self._get_trace_and_span_info( ) self._self_recorder.push_event( LockAcquireEvent( lock_name=self._self_name, frames=frames, nframes=nframes, thread_id=thread_id, thread_name=thread_name, trace_id=trace_id, span_id=span_id, trace_resource=trace_resource, trace_type=trace_type, wait_time_ns=end - start, sampling_pct=self._self_capture_sampler.capture_pct, )) except Exception: pass
def acquire(self, *args, **kwargs): if not self._self_capture_sampler.capture(): return self.__wrapped__.acquire(*args, **kwargs) start = compat.monotonic_ns() try: return self.__wrapped__.acquire(*args, **kwargs) finally: try: end = self._self_acquired_at = compat.monotonic_ns() thread_id, thread_name = _current_thread() frames, nframes = _traceback.pyframe_to_frames(sys._getframe(1), self._self_max_nframes) task_id, task_name = _task.get_task(thread_id) event = LockAcquireEvent( lock_name=self._self_name, frames=frames, nframes=nframes, thread_id=thread_id, thread_name=thread_name, task_id=task_id, task_name=task_name, wait_time_ns=end - start, sampling_pct=self._self_capture_sampler.capture_pct, ) if self._self_tracer is not None: event.set_trace_info(self._self_tracer.current_span(), self._self_endpoint_collection_enabled) self._self_recorder.push_event(event) except Exception: pass
def test_rate_liimter_effective_rate_rates(): limiter = RateLimiter(rate_limit=100) # Static rate limit window starting_window_ns = compat.monotonic_ns() for _ in range(100): assert limiter.is_allowed(starting_window_ns) is True assert limiter.effective_rate == 1.0 assert limiter.current_window_ns == starting_window_ns for i in range(1, 101): assert limiter.is_allowed(starting_window_ns) is False rate = 100 / (100 + i) assert limiter.effective_rate == rate assert limiter.current_window_ns == starting_window_ns prev_rate = 0.5 window_ns = starting_window_ns + 1e9 for i in range(100): assert limiter.is_allowed(window_ns) is True assert limiter.effective_rate == 0.75 assert limiter.current_window_ns == window_ns for i in range(1, 101): assert limiter.is_allowed(window_ns) is False rate = 100 / (100 + i) assert limiter.effective_rate == (rate + prev_rate) / 2 assert limiter.current_window_ns == window_ns
def release(self, *args, **kwargs): try: return self.__wrapped__.release(*args, **kwargs) finally: try: if hasattr(self, "_self_acquired_at"): try: end = compat.monotonic_ns() frames, nframes = _traceback.pyframe_to_frames( sys._getframe(1), self._self_max_nframes) thread_id, thread_name = _current_thread() trace_ids, span_ids = self._get_trace_and_span_ids() self._self_recorder.push_event( LockReleaseEvent( lock_name=self._self_name, frames=frames, nframes=nframes, thread_id=thread_id, thread_name=thread_name, trace_ids=trace_ids, span_ids=span_ids, locked_for_ns=end - self._self_acquired_at, sampling_pct=self._self_capture_sampler. capture_pct, )) finally: del self._self_acquired_at except Exception: pass
def release(self, *args, **kwargs): try: return self.__wrapped__.release(*args, **kwargs) finally: try: if hasattr(self, "_self_acquired_at"): try: end = compat.monotonic_ns() frames, nframes = _traceback.pyframe_to_frames(sys._getframe(1), self._self_max_nframes) thread_id, thread_name = _current_thread() task_id, task_name = _task.get_task(thread_id) event = LockReleaseEvent( lock_name=self._self_name, frames=frames, nframes=nframes, thread_id=thread_id, thread_name=thread_name, task_id=task_id, task_name=task_name, locked_for_ns=end - self._self_acquired_at, sampling_pct=self._self_capture_sampler.capture_pct, ) if self._self_tracer is not None: event.set_trace_info( self._self_tracer.current_span(), self._self_endpoint_collection_enabled ) self._self_recorder.push_event(event) finally: del self._self_acquired_at except Exception: pass
def test_rate_limiter_rate_limit_negative(): limiter = RateLimiter(rate_limit=-1) assert limiter.rate_limit == -1 assert limiter.tokens == -1 assert limiter.max_tokens == -1 now_ns = compat.monotonic_ns() for i in nanoseconds(10000): # Make sure the time is different for every check assert limiter.is_allowed(now_ns + i) is True
def test_rate_limiter_is_allowed_small_gaps(): limiter = RateLimiter(rate_limit=100) # Start time now_ns = compat.monotonic_ns() gap = 1e9 / 100 # Keep incrementing by a gap to keep us at our rate limit for i in nanoseconds(10000): # Keep the same timeframe time_ns = now_ns + (gap * i) assert limiter.is_allowed(time_ns) is True
def test_rate_limiter_is_allowed_large_gap(): limiter = RateLimiter(rate_limit=100) # Start time now_ns = compat.monotonic_ns() # Keep the same timeframe for _ in range(100): assert limiter.is_allowed(now_ns) is True # Large gap before next call to `is_allowed()` for _ in range(100): assert limiter.is_allowed(now_ns + (1e9 * 100)) is True
def test_rate_limiter_effective_rate_starting_rate(): limiter = RateLimiter(rate_limit=1) now_ns = compat.monotonic_ns() # Default values assert limiter.current_window_ns == 0 assert limiter.prev_window_rate is None # Accessing the effective rate doesn't change anything assert limiter.effective_rate == 1.0 assert limiter.current_window_ns == 0 assert limiter.prev_window_rate is None # Calling `.is_allowed()` updates the values assert limiter.is_allowed(now_ns) is True assert limiter.effective_rate == 1.0 assert limiter.current_window_ns == now_ns assert limiter.prev_window_rate is None # Gap of 0.9999 seconds, same window time_ns = now_ns + (0.9999 * 1e9) assert limiter.is_allowed(time_ns) is False # DEV: We have rate_limit=1 set assert limiter.effective_rate == 0.5 assert limiter.current_window_ns == now_ns assert limiter.prev_window_rate is None # Gap of 1.0 seconds, new window time_ns = now_ns + 1e9 assert limiter.is_allowed(time_ns) is True assert limiter.effective_rate == 0.75 assert limiter.current_window_ns == (now_ns + 1e9) assert limiter.prev_window_rate == 0.5 # Gap of 1.9999 seconds, same window time_ns = now_ns + (1.9999 * 1e9) assert limiter.is_allowed(time_ns) is False assert limiter.effective_rate == 0.5 assert limiter.current_window_ns == (now_ns + 1e9) # Same as old window assert limiter.prev_window_rate == 0.5 # Large gap of 100 seconds, new window time_ns = now_ns + (100.0 * 1e9) assert limiter.is_allowed(time_ns) is True assert limiter.effective_rate == 0.75 assert limiter.current_window_ns == (now_ns + (100.0 * 1e9)) assert limiter.prev_window_rate == 0.5
def release( self, *args, # type: typing.Any **kwargs # type: typing.Any ): # type: (...) -> None try: return self.__wrapped__.release(*args, **kwargs) finally: try: if hasattr(self, "_self_acquired_at"): try: end = compat.monotonic_ns() thread_id, thread_name = _current_thread() task_id, task_name, task_frame = _task.get_task( thread_id) if task_frame is None: frame = sys._getframe(1) else: frame = task_frame frames, nframes = _traceback.pyframe_to_frames( frame, self._self_max_nframes) event = self.RELEASE_EVENT_CLASS( # type: ignore[call-arg] lock_name=self._self_name, frames=frames, nframes=nframes, thread_id=thread_id, thread_name=thread_name, task_id=task_id, task_name=task_name, locked_for_ns=end - self._self_acquired_at, sampling_pct=self._self_capture_sampler. capture_pct, ) if self._self_tracer is not None: event.set_trace_info( self._self_tracer.current_span(), self._self_endpoint_collection_enabled) self._self_recorder.push_event(event) finally: del self._self_acquired_at except Exception: pass
def test_rate_limiter_is_allowed(rate_limit): limiter = RateLimiter(rate_limit=rate_limit) def check_limit(time_ns): # Up to the allowed limit is allowed for _ in range(rate_limit): assert limiter.is_allowed(time_ns) is True # Any over the limit is disallowed for _ in range(1000): assert limiter.is_allowed(time_ns) is False # Start time now = compat.monotonic_ns() # Check the limit for 5 time frames for i in nanoseconds(5): # Keep the same timeframe check_limit(now + i)
def test_rate_limiter_init(): limiter = RateLimiter(rate_limit=100) assert limiter.rate_limit == 100 assert limiter.tokens == 100 assert limiter.max_tokens == 100 assert limiter.last_update_ns <= compat.monotonic_ns()
def spend_cpu_3(): # Active wait for 3 seconds now = compat.monotonic_ns() while compat.monotonic_ns() - now < 3e9: pass
def spend_cpu_2(): now = compat.monotonic_ns() # Active wait for 2 seconds while compat.monotonic_ns() - now < 2e9: pass