Class: Lanet::Ping

Inherits:
Object
  • Object
show all
Defined in:
lib/lanet/ping.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(timeout: 1, count: 3) ⇒ Ping

Returns a new instance of Ping.



11
12
13
14
15
# File 'lib/lanet/ping.rb', line 11

def initialize(timeout: 1, count: 3)
  @timeout = timeout
  @count = count
  @continuous = false
end

Instance Attribute Details

#countObject (readonly)

Returns the value of attribute count.



9
10
11
# File 'lib/lanet/ping.rb', line 9

def count
  @count
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



9
10
11
# File 'lib/lanet/ping.rb', line 9

def timeout
  @timeout
end

Instance Method Details

#ping_host(host, realtime = false, continuous = false) ⇒ Hash

Ping a single host with real-time output

Parameters:

  • host (String)

    The IP address or hostname to ping

  • realtime (Boolean) (defaults to: false)

    Whether to print output in real-time

  • continuous (Boolean) (defaults to: false)

    Whether to ping continuously until interrupted

Returns:

  • (Hash)

    Result with status, response time, and output



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/lanet/ping.rb', line 22

def ping_host(host, realtime = false, continuous = false)
  @continuous = continuous

  result = {
    host: host,
    status: false,
    response_time: nil,
    packet_loss: 100,
    output: "",
    responses: [] # Store individual ping responses
  }

  begin
    # Command varies by OS
    ping_cmd = ping_command(host)

    # Use different approaches based on output mode
    if realtime
      process_realtime_ping(ping_cmd, result)
    else
      # Use backticks for quiet mode - much more reliable than Open3 for this case
      process_quiet_ping(ping_cmd, result)
    end
  rescue Timeout::Error
    result[:output] = "Ping timed out after #{@timeout * 2} seconds"
  rescue Interrupt
    # Handle Ctrl+C gracefully for continuous mode
    print_ping_statistics(host, result) if realtime
    exit(0) if realtime # Only exit if in realtime mode - otherwise let the caller handle it
  rescue StandardError => e
    result[:output] = "Error: #{e.message}"
  end

  # Only print statistics in realtime mode and not continuous
  print_ping_statistics(host, result) if realtime && !@continuous

  result
end

#ping_hosts(hosts, realtime = false, continuous = false) ⇒ Hash

Ping multiple hosts in parallel

Parameters:

  • hosts (Array<String>)

    Array of IP addresses or hostnames

  • realtime (Boolean) (defaults to: false)

    Whether to print output in real-time

  • continuous (Boolean) (defaults to: false)

    Whether to ping continuously until interrupted

Returns:

  • (Hash)

    Results indexed by host



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/lanet/ping.rb', line 80

def ping_hosts(hosts, realtime = false, continuous = false)
  results = {}
  if realtime
    # For real-time output, run pings sequentially
    hosts.each do |host|
      results[host] = ping_host(host, true, continuous)
      puts "\n" unless host == hosts.last
    end
  else
    # For non-realtime output, run pings in parallel
    threads = []

    hosts.each do |host|
      threads << Thread.new do
        results[host] = ping_host(host)
      end
    end

    threads.each(&:join)
  end
  results
end

#reachable?(host) ⇒ Boolean

Check if a host is reachable

Parameters:

  • host (String)

    The IP address or hostname to check

Returns:

  • (Boolean)

    True if the host is reachable



64
65
66
# File 'lib/lanet/ping.rb', line 64

def reachable?(host)
  ping_host(host)[:status]
end

#response_time(host) ⇒ Float?

Get the response time for a host

Parameters:

  • host (String)

    The IP address or hostname to check

Returns:

  • (Float, nil)

    The response time in ms, or nil if unreachable



71
72
73
# File 'lib/lanet/ping.rb', line 71

def response_time(host)
  ping_host(host)[:response_time]
end