Class: Datadog::Profiling::Scheduler
- Inherits:
-
Core::Worker
- Object
- Core::Worker
- Datadog::Profiling::Scheduler
- Includes:
- Core::Workers::Polling
- Defined in:
- lib/datadog/profiling/scheduler.rb
Overview
Periodically (every interval, 60 seconds by default) takes a profile from the ‘Exporter` and reports it using the configured transport. Runs on its own background thread.
Constant Summary collapse
- MINIMUM_INTERVAL_SECONDS =
0
- DEFAULT_FLUSH_JITTER_MAXIMUM_SECONDS =
We sleep for at most this duration seconds before reporting data to avoid multi-process applications all reporting profiles at the exact same time
3
Constants included from Core::Workers::Polling
Core::Workers::Polling::DEFAULT_SHUTDOWN_TIMEOUT
Instance Attribute Summary
Attributes inherited from Core::Worker
Instance Method Summary collapse
-
#initialize(exporter:, transport:, interval:, fork_policy: Core::Workers::Async::Thread::FORK_POLICY_RESTART, enabled: true) ⇒ Scheduler
constructor
A new instance of Scheduler.
-
#loop_wait_before_first_iteration? ⇒ Boolean
Configure Workers::IntervalLoop to not report immediately when scheduler starts.
-
#mark_profiler_failed ⇒ Object
This is called by the Profiler class whenever an issue happened in the profiler.
- #perform(on_failure_proc) ⇒ Object
- #reset_after_fork ⇒ Object
- #start(on_failure_proc: nil) ⇒ Object
- #work_pending? ⇒ Boolean
Methods included from Core::Workers::Polling
#enabled=, #enabled?, included, #stop
Constructor Details
#initialize(exporter:, transport:, interval:, fork_policy: Core::Workers::Async::Thread::FORK_POLICY_RESTART, enabled: true) ⇒ Scheduler
Returns a new instance of Scheduler.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/datadog/profiling/scheduler.rb', line 31 def initialize( exporter:, transport:, interval:, fork_policy: Core::Workers::Async::Thread::FORK_POLICY_RESTART, # Restart in forks by default, # seconds enabled: true ) @exporter = exporter @transport = transport @profiler_failed = false @stop_requested = false # Workers::Async::Thread settings self.fork_policy = fork_policy # Workers::IntervalLoop settings self.loop_base_interval = interval # Workers::Polling settings self.enabled = enabled end |
Instance Method Details
#loop_wait_before_first_iteration? ⇒ Boolean
Configure Workers::IntervalLoop to not report immediately when scheduler starts
When a scheduler gets created (or reset), we don’t want it to immediately try to flush; we want it to wait for the loop wait time first. This avoids an issue where the scheduler reported a mostly-empty profile if the application just started but this thread took a bit longer so there’s already profiling data in the exporter.
82 83 84 |
# File 'lib/datadog/profiling/scheduler.rb', line 82 def loop_wait_before_first_iteration? true end |
#mark_profiler_failed ⇒ Object
This is called by the Profiler class whenever an issue happened in the profiler. This makes sure that even if there is data to be flushed, we don’t try to flush it.
88 89 90 |
# File 'lib/datadog/profiling/scheduler.rb', line 88 def mark_profiler_failed @profiler_failed = true end |
#perform(on_failure_proc) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/datadog/profiling/scheduler.rb', line 56 def perform(on_failure_proc) # A profiling flush may be called while the VM is shutting down, to report the last profile. When we do so, # we impose a strict timeout. This means this last profile may or may not be sent, depending on if the flush can # successfully finish in the strict timeout. # This can be somewhat confusing (why did it not get reported?), so let's at least log what happened. interrupted = true flush_and_wait interrupted = false rescue Exception => e # rubocop:disable Lint/RescueException Datadog.logger.warn( "Profiling::Scheduler thread error. " \ "Cause: #{e.class.name} #{e.} Location: #{Array(e.backtrace).first}" ) on_failure_proc&.call Datadog::Core::Telemetry::Logger.report(e, description: "Profiling::Scheduler thread error") raise ensure Datadog.logger.debug("#flush was interrupted or failed before it could complete") if interrupted end |
#reset_after_fork ⇒ Object
96 97 98 |
# File 'lib/datadog/profiling/scheduler.rb', line 96 def reset_after_fork exporter.reset_after_fork end |
#start(on_failure_proc: nil) ⇒ Object
52 53 54 |
# File 'lib/datadog/profiling/scheduler.rb', line 52 def start(on_failure_proc: nil) perform(on_failure_proc) end |
#work_pending? ⇒ Boolean
92 93 94 |
# File 'lib/datadog/profiling/scheduler.rb', line 92 def work_pending? !profiler_failed && exporter.can_flush? && (run_loop? || !stop_requested?) end |