Class: Knj::Unix_proc

Inherits:
Object show all
Defined in:
lib/knj/unix_proc.rb

Overview

This class handels various stuff regarding Unix-processes.

Constant Summary collapse

PROCS =
Wref::Map.new
MUTEX =
Mutex.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ Unix_proc

Initializes various data for a Unix_proc-object. This should not be called manually but through “Unix_proc.list”.



122
123
124
# File 'lib/knj/unix_proc.rb', line 122

def initialize(data)
  @data = data
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



6
7
8
# File 'lib/knj/unix_proc.rb', line 6

def data
  @data
end

Class Method Details

.find_selfObject

Returns the “Knj::Unix_proc” for the current process.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/knj/unix_proc.rb', line 96

def self.find_self
  procs = Knj::Unix_proc.list("ignore_self" => false)
  pid_find = Process.pid

  proc_find = false
  procs.each do |proc_ele|
    if proc_ele["pid"].to_i == pid_find.to_i
      proc_find = proc_ele
      break
    end
  end

  return proc_find
end

.list(args = {}) ⇒ Object

Returns an array with (or yields if block given) Unix_proc. Hash-arguments as ‘grep’.



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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/knj/unix_proc.rb', line 27

def self.list(args = {})
  cmdstr = "ps aux"
  grepstr = ""

  if args["grep"]
    grepstr = "grep #{args["grep"]}" #used for ignoring the grep-process later.
    cmdstr << " | grep #{Knj::Strings.unixsafe(args["grep"])}"
  end

  MUTEX.synchronize do
    ret = [] unless block_given?

    if args["psaux_str"]
      res = args["psaux_str"]
    else
      res = Knj::Os.shellcmd(cmdstr)
    end

    res.scan(/^(\S+)\s+([0-9]+)\s+([0-9.]+)\s+([0-9.]+)\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+ (.+)($|\n)/) do |match|
      pid = match[1]

      data = {
        "user" => match[0],
        "pid" => pid,
        "cpu_last" => match[2],
        "ram_last" => match[3],
        "cmd" => match[4],
        "app" => File.basename(match[4])
      }

      next if (!args.key?("ignore_self") or args["ignore_self"]) and match[1].to_i == $$.to_i
      next if grepstr.length > 0 and match[4].index(grepstr) != nil #dont return current process.

      if args.key?("pids")
        found = false
        args["pids"].each do |pid_given|
          if pid_given.to_s == pid.to_s
            found = true
            break
          end
        end

        next if !found
      end

      if args["yield_data"]
        yield(data)
      else
        proc_obj = Knj::Unix_proc.spawn(data)

        if block_given?
          yield(proc_obj)
        else
          ret << proc_obj
        end
      end
    end

    PROCS.clean

    if block_given?
      return nil
    else
      return ret
    end
  end
end

.pid_running?(pid) ⇒ Boolean

Return true if the given PID is running.

Returns:

  • (Boolean)


112
113
114
115
116
117
118
119
# File 'lib/knj/unix_proc.rb', line 112

def self.pid_running?(pid)
  begin
    Process.getpgid(pid)
    return true
  rescue Errno::ESRCH
    return false
  end
end

.spawn(data) ⇒ Object

Spawns a process if it doesnt already exist in the wrap-map.



12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/knj/unix_proc.rb', line 12

def self.spawn(data)
  pid = data["pid"].to_i

  begin
    proc_ele = PROCS.get!(pid)
    proc_ele.update_data(data)
  rescue Wref::Recycled
    proc_ele = Knj::Unix_proc.new(data)
    PROCS[pid] = proc_ele
  end

  return proc_ele
end

Instance Method Details

#[](key) ⇒ Object

Returns a key from the data or raises an error.



137
138
139
140
# File 'lib/knj/unix_proc.rb', line 137

def [](key)
  raise "No such data: #{key}" if !@data.key?(key)
  return @data[key]
end

#alive?Boolean

Returns true if the process is still alive.

Returns:

  • (Boolean)


180
181
182
# File 'lib/knj/unix_proc.rb', line 180

def alive?
  return Knj::Unix_proc.pid_running?(@data["pid"].to_i)
end

#killObject

Kills the process.



143
144
145
# File 'lib/knj/unix_proc.rb', line 143

def kill
  Process.kill("TERM", @data["pid"].to_i)
end

#kill!Object

Kills the process with 9.



148
149
150
# File 'lib/knj/unix_proc.rb', line 148

def kill!
  Process.kill(9, @data["pid"].to_i)
end

#kill_ensure(args = {}) ⇒ Object

Tries to kill the process gently, waits a couple of secs to check if the process is actually dead, then sends -9 kill signals.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/knj/unix_proc.rb', line 158

def kill_ensure(args = {})
  begin
    self.kill
    sleep 0.1
    return nil if !self.alive?

    args[:sleep] = 2 if !args.key(:sleep)

    0.upto(5) do
      sleep args[:sleep]
      self.kill!
      sleep 0.1
      return nil if !self.alive?
    end

    raise "Could not kill the process."
  rescue Errno::ESRCH
    return nil
  end
end

#pidObject

Returns the PID of the process.



132
133
134
# File 'lib/knj/unix_proc.rb', line 132

def pid
  return @data["pid"].to_i
end

#to_hObject

Hash-compatible.



153
154
155
# File 'lib/knj/unix_proc.rb', line 153

def to_h
  return @data.clone
end

#update_data(data) ⇒ Object

Updates the data. This should not be called manually, but is exposed because of various code in “Unix_proc.list”.



127
128
129
# File 'lib/knj/unix_proc.rb', line 127

def update_data(data)
  @data = data
end