Kiln » Kiln Storage Service Read More
Clone URL:  
proc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
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
94
95
96
97
98
99
import os import subprocess import tempfile import time from bugzscout import report_exception, report_error MAX_RUN_TIME = 30 * 60 # 30 Minutes BACKEND_AREA = 'Backend' def start_proc(*args, **kwargs): try: outfile = tempfile.TemporaryFile() errfile = tempfile.TemporaryFile() proc = subprocess.Popen(args, stdout=outfile, stderr=errfile) proc.args = args proc.timeout = time.time() + kwargs.get('timeout', MAX_RUN_TIME) proc.outfile = outfile proc.errfile = errfile return proc except Exception, e: extra = "Failed to start '%s'\n" % ' '.join(args) report_exception(e, extra, area=kwargs.get('bugzscout_area', BACKEND_AREA)) def monitor_proc(proc, **kwargs): retval = True if not proc: # We can't monitor nothing. Something probably failed in process creation. return False ret_code = None while ret_code is None: ret_code = proc.poll() time.sleep(0.50) if time.time() > proc.timeout: # Time's up. Now you die. ret_code = kill_proc(proc) break if ret_code: # Something went wrong. Log it and put the repos back in the queue. args = ' '.join(proc.args) proc.outfile.seek(0) proc.errfile.seek(0) out = proc.outfile.read() err = proc.errfile.read() extra = '\n'.join([ 'Command exited with code %s' % proc.returncode, args, '================StdErr==================', err, '================StdOut==================', out, ]) report_error('Error running %s' % proc.args[0], extra, area=kwargs.get('bugzscout_area', BACKEND_AREA)) retval = False proc.outfile.close() proc.errfile.close() return retval def kill_proc(proc): if os.name == 'posix': # POSIX: os.kill sends signals. from signal import SIGTERM, SIGKILL os.kill(proc.pid, SIGTERM) time.sleep(30) # You have 30 seconds to die ret_code = proc.poll() if not ret_code: # Not dead yet...kill it again. os.kill(proc.pid, SIGKILL) ret_code = proc.poll() or -1 return ret_code else: # Windows: We have to use TerminateProcess win_kill_tree(proc.pid) time.sleep(30) return proc.poll() or -1 def win_get_children(pid): import win32com.client wmi = win32com.client.GetObject('winmgmts:') children = wmi.ExecQuery('SELECT * FROM win32_process WHERE ParentProcessId=%s' % pid) pids = [] for proc in children: pids.append(proc.Properties_('ProcessId')) return pids def win_kill_pid(pid): import win32api import win32con import win32process handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, False, pid) win32process.TerminateProcess(handle, 1) def win_kill_tree(pid): children = win_get_children(pid) win_kill_pid(pid) for child in children: win_kill_tree(child) time.sleep(0.1)