Skip to content

Commit

Permalink
as per comment attached to #477, rename sendXSignal to signalX, dont …
Browse files Browse the repository at this point in the history
…do anything async in signalGroup, merge logic for _stopresult and _signalresult in supervisorctl
  • Loading branch information
mcdonc authored and mnaberez committed Aug 18, 2015
1 parent 5e7d8ae commit 813787f
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 50 deletions.
4 changes: 2 additions & 2 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,9 @@ Process Control

.. automethod:: stopAllProcesses

.. automethod:: sendProcessSignal
.. automethod:: signalProcess

.. automethod:: sendGroupSignal
.. automethod:: signalGroup

.. automethod:: sendProcessStdin

Expand Down
2 changes: 1 addition & 1 deletion supervisor/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ def signal(self, sig):

try:
options.kill(self.pid, sig)
except Exception, e:
except Exception:
io = StringIO.StringIO()
traceback.print_exc(file=io)
tb = io.getvalue()
Expand Down
22 changes: 9 additions & 13 deletions supervisor/rpcinterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import datetime
import errno
import types
import signal

from supervisor.datatypes import signal_number

Expand Down Expand Up @@ -462,21 +461,21 @@ def stopAllProcesses(self, wait=True):
return killall # deferred


def sendProcessSignal(self, name, signal='HUP'):
def signalProcess(self, name, signal='HUP'):
""" Send an arbitrary UNIX signal to the process named by name
@param string name The name of the process to signal (or 'group:name')
@param int signal the integer UNIX signal to send. SIGHUP by default.
@return boolean result
"""

self._update('sendProcessSignal')
self._update('signalProcess')

group, process = self._getGroupAndProcess(name)

if process is None:
group_name, process_name = split_namespec(name)
return self.sendGroupSignal(group_name, signal=signal)
return self.signalGroup(group_name, signal=signal)

try:
sig = signal_number(signal)
Expand All @@ -494,32 +493,29 @@ def sendProcessSignal(self, name, signal='HUP'):
return True


def sendGroupSignal(self, name, signal='HUP'):
def signalGroup(self, name, signal='HUP'):
""" Send a signal to all processes in the group named 'name'
@param string name The group name
@param int signal The signal to be sent. SIGHUP by default
@return array result
"""

self._update('sendGroupSignal')
self._update('signalGroup')

group = self.supervisord.process_groups.get(name)

if group is None:
raise RPCError(Faults.BAD_NAME, name)

processes = group.processes.values()
processes.sort()
processes = [(group, process) for process in processes]

sendall = make_allfunc(processes, isRunning, self.sendProcessSignal,
sendall = make_allfunc(processes, isRunning, self.signalProcess,
signal=signal)
sendall.rpcinterface = self
result = sendall()
self._update('signalGroup')

sendall.delay = 0
sendall.rpcinterface = self
return sendall
return result


def getAllConfigInfo(self):
Expand Down
27 changes: 7 additions & 20 deletions supervisor/supervisorctl.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,23 +747,7 @@ def help_start(self):
"start <name> <name>\tStart multiple processes or groups")
self.ctl.output("start all\t\tStart all processes")

def _stopresult(self, result):
name = make_namespec(result['group'], result['name'])
code = result['status']
fault_string = result['description']
template = '%s: ERROR (%s)'
if code == xmlrpc.Faults.BAD_NAME:
return template % (name, 'no such process')
elif code == xmlrpc.Faults.NOT_RUNNING:
return template % (name, 'not running')
elif code == xmlrpc.Faults.SUCCESS:
return '%s: stopped' % name
elif code == xmlrpc.Faults.FAILED:
return fault_string
# assertion
raise ValueError('Unknown result code %s for %s' % (code, name))

def _signalresult(self, result):
def _signalresult(self, result, success='signalled'):
name = make_namespec(result['group'], result['name'])
code = result['status']
fault_string = result['description']
Expand All @@ -775,12 +759,15 @@ def _signalresult(self, result):
elif code == xmlrpc.Faults.NOT_RUNNING:
return template % (name, 'not running')
elif code == xmlrpc.Faults.SUCCESS:
return '%s: signalled' % name
return '%s: %s' % (name, success)
elif code == xmlrpc.Faults.FAILED:
return fault_string
# assertion
raise ValueError('Unknown result code %s for %s' % (code, name))

def _stopresult(self, result):
return self._signalresult(result, success='stopped')

def do_stop(self, arg):
if not self.ctl.upcheck():
return
Expand Down Expand Up @@ -858,7 +845,7 @@ def do_signal(self, arg):
group_name, process_name = split_namespec(name)
if process_name is None:
try:
results = supervisor.sendGroupSignal(group_name, sig)
results = supervisor.signalGroup(group_name, sig)
for result in results:
result = self._signalresult(result)
self.ctl.output(result)
Expand All @@ -870,7 +857,7 @@ def do_signal(self, arg):
raise
else:
try:
supervisor.sendProcessSignal(name, sig)
supervisor.signalProcess(name, sig)
except xmlrpclib.Fault as e:
error = self._signalresult({'status': e.faultCode,
'name': process_name,
Expand Down
23 changes: 9 additions & 14 deletions supervisor/tests/test_rpcinterfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,22 +838,22 @@ def test_stopAllProcesses_nowait(self):
]
)

def test_sendProcessSignal(self):
def test_signalProcess(self):
options = DummyOptions()
pconfig = DummyPConfig(options, 'foo', '/bin/foo')
from supervisor.process import ProcessStates
supervisord = PopulatedDummySupervisor(options, 'foo', pconfig)
supervisord.set_procattr('foo', 'state', ProcessStates.RUNNING)
interface = self._makeOne(supervisord)

result = interface.sendProcessSignal('foo', 10)
result = interface.signalProcess('foo', 10)

self.assertEqual(interface.update_text, 'sendProcessSignal')
self.assertEqual(interface.update_text, 'signalProcess')
self.assertEqual(result, True)
p = supervisord.process_groups[supervisord.group_name].processes['foo']
self.assertEqual(p.sent_signal, 10 )

def test_sendGroupSignal(self):
def test_signalGroup(self):
options = DummyOptions()
pconfig1 = DummyPConfig(options, 'process1', '/bin/foo')
pconfig2 = DummyPConfig(options, 'process2', '/bin/foo2')
Expand All @@ -863,8 +863,8 @@ def test_sendGroupSignal(self):
supervisord.set_procattr('process1', 'state', ProcessStates.RUNNING)
supervisord.set_procattr('process2', 'state', ProcessStates.RUNNING)
interface = self._makeOne(supervisord)
callback = interface.sendGroupSignal('foo', 10)
self.assertEqual(interface.update_text, 'sendGroupSignal')
callback = interface.signalGroup('foo', 10)
self.assertEqual(interface.update_text, 'signalGroup')
from supervisor import http

result = http.NOT_DONE_YET
Expand All @@ -883,7 +883,7 @@ def test_sendGroupSignal(self):
process2 = supervisord.process_groups['foo'].processes['process2']
self.assertEqual(process2.sent_signal, 10)

def test_sendProcessGroupSignal(self):
def test_signalGroup(self):
""" Test that sending foo:* works """
options = DummyOptions()
pconfig1 = DummyPConfig(options, 'process1', '/bin/foo')
Expand All @@ -894,14 +894,9 @@ def test_sendProcessGroupSignal(self):
supervisord.set_procattr('process1', 'state', ProcessStates.RUNNING)
supervisord.set_procattr('process2', 'state', ProcessStates.RUNNING)
interface = self._makeOne(supervisord)
callback = interface.sendProcessSignal('foo:*', 10)
self.assertEqual(interface.update_text, 'sendGroupSignal')
from supervisor import http
result = interface.signalProcess('foo:*', 10)
self.assertEqual(interface.update_text, 'signalGroup')

result = http.NOT_DONE_YET
while result is http.NOT_DONE_YET:
result = callback()

# Sort so we get deterministic results despite hash randomization
result = sorted(result, key=operator.itemgetter('name'))

Expand Down

0 comments on commit 813787f

Please sign in to comment.