Module: Polyrun::WorkerPing

Defined in:
lib/polyrun/worker_ping.rb,
sig/polyrun/worker_ping.rbs

Overview

Writes a monotonic timestamp to POLYRUN_WORKER_PING_FILE when the test process advances (typically once per example). When location: is passed (path:line of the example), the file is two lines: timestamp, then that string. Parents use --worker-idle-timeout to detect a worker with no progress inside a single example—unlike a background thread, ping! does not run while Ruby is busy on the main thread, so a tight CPU loop or stuck native code leaves the timestamp stale.

Prefer framework installs (call from helpers after loading the runner):

require "polyrun/rspec"
Polyrun::RSpec.install_worker_ping!

require "polyrun/minitest"
Polyrun::Minitest.install_worker_ping!

Polyrun Quick runs ping! automatically when requiring the Quick stack.

Optional interval thread (+POLYRUN_WORKER_PING_THREAD=1+, POLYRUN_WORKER_PING_INTERVAL_SEC): call #ensure_interval_ping_thread! once at worker startup if you rely on periodic pings without per-example #ping!; installers call this so the env toggle works out of the box.

Class Method Summary collapse

Class Method Details

.ensure_interval_ping_thread!void

This method returns an undefined value.

Idempotent — installers call once; POLYRUN_WORKER_PING_THREAD gates the periodic thread.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/polyrun/worker_ping.rb', line 42

def ensure_interval_ping_thread!
  thread_flag = ENV["POLYRUN_WORKER_PING_THREAD"]
  return unless %w[1 true yes].include?(thread_flag&.downcase)

  path = ping_file_path
  return if path.empty?

  @interval_ping_mx ||= Mutex.new
  @interval_ping_mx.synchronize do
    return if @interval_ping_started

    raw = ENV["POLYRUN_WORKER_PING_INTERVAL_SEC"].to_s.strip
    interval = Float(raw.empty? ? "15" : raw, exception: false) || 15.0
    interval = 1.0 if interval < 1.0

    ping!
    # rubocop:disable ThreadSafety/NewThread -- optional periodic ping alongside per-example ping!
    Thread.new do
      loop do
        sleep(interval)
        ping!
      rescue SystemCallError, Interrupt
        break
      end
    end
    # rubocop:enable ThreadSafety/NewThread
    @interval_ping_started = true
  end
end

.ping!(location: nil) ⇒ void

This method returns an undefined value.

Parameters:

  • location: (String, nil) (defaults to: nil)


23
24
25
26
27
28
29
30
31
32
33
# File 'lib/polyrun/worker_ping.rb', line 23

def ping!(location: nil)
  path = ping_file_path
  return if path.empty?

  t = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_s
  loc = location.to_s.strip
  payload = loc.empty? ? t : "#{t}\n#{loc}"
  File.binwrite(path, payload)
rescue SystemCallError
  # best-effort
end

.ping_file_pathString

Returns:

  • (String)


35
36
37
# File 'lib/polyrun/worker_ping.rb', line 35

def ping_file_path
  ENV["POLYRUN_WORKER_PING_FILE"].to_s.strip
end