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”.



113
114
115
# File 'lib/knj/unix_proc.rb', line 113

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.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/knj/unix_proc.rb', line 87

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
# 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?
    res = Knj::Os.shellcmd(cmdstr)
    
    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
      
      proc_obj = Knj::Unix_proc.spawn(data)
      
      if block_given?
        yield(proc_obj)
      else
        ret << proc_obj
      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)


103
104
105
106
107
108
109
110
# File 'lib/knj/unix_proc.rb', line 103

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.



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

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)


171
172
173
# File 'lib/knj/unix_proc.rb', line 171

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

#killObject

Kills the process.



134
135
136
# File 'lib/knj/unix_proc.rb', line 134

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

#kill!Object

Kills the process with 9.



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

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.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/knj/unix_proc.rb', line 149

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.



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

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

#to_hObject

Hash-compatible.



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

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”.



118
119
120
# File 'lib/knj/unix_proc.rb', line 118

def update_data(data)
  @data = data
end