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[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