Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def clean_service(service_path):
# we use SIGTERM; SIGKILL is cheating.
limit = 100
while limit > 0: # pragma: no branch: we don't expect to ever hit the limit
assert os.path.isdir(service_path), service_path
try:
show_runaway_processes(service_path)
print('lock released -- done.')
break
except LockHeld:
print('lock held -- killing!')
for pid in fuser(service_path):
try:
os.system('ps -fj %i' % pid)
os.kill(pid, signal.SIGTERM)
except OSError as error: # race condition -- process stopped between list and kill :pragma: no-cover
if error.errno == 3: # no such process
pass
else:
raise
limit -= 1
def it_kills_processes_holding_the_lock(self, tmpdir):
lockfile = tmpdir.ensure('lock')
lock = lockfile.open()
process = Popen(('sleep', 'infinity'))
lock.close()
# assert `process` has `lock`
assert list(fuser(lockfile.strpath)) == [process.pid]
with mock.patch('sys.stderr', new_callable=StringIO.StringIO) as mock_stderr:
terminate_runaway_processes(lockfile.strpath)
assert 'WARNING: Killing these runaway ' in mock_stderr.getvalue()
wait_for(lambda: process.poll() == -9)
def on_lock_held(path):
reraise(LockHeld(
'another pgctl command is currently managing this service: (%s)\n%s' %
(bestrelpath(path), ps(fuser(path)))
))
def show_runaway_processes(path):
from .fuser import fuser
processes = ps(fuser(path))
if processes:
raise LockHeld(
'''\
these runaway processes did not stop:
%s
There are two ways you can fix this:
* temporarily: pgctl stop %s --force
* permanently: http://pgctl.readthedocs.org/en/latest/user/quickstart.html#writing-playground-services
''' % (processes, os.path.basename(path))
)
else:
pass
def terminate_runaway_processes(path):
"""forcefully kill processes holding the lock to `path`"""
from .fuser import fuser
pids = list(fuser(path))
processes = ps(pids)
if processes:
print_stderr('''[pgctl] WARNING: Killing these runaway processes at user's request (--force):
{}
Learn why they did not stop: http://pgctl.readthedocs.org/en/latest/user/quickstart.html#writing-playground-services
'''.format(processes)
)
for pid in pids:
try:
os.kill(pid, signal.SIGKILL)
except OSError: # pragma: no cover
# race condition: processes stopped slightly after timeout, before we kill it
pass