Javier Matos Odut
2015-08-02 23:52:08 UTC
Hi,
I plan to develop a web user interface for supervisor and share it with
the community (I know that there are some UI out there, but I prefer to
create mine). I want to create my own because I need to integrate the UI
with the "supervisor-quick" extension
(https://pypi.python.org/pypi/supervisor-quick/0.1.3). I have a
production server which takes a lot by using the built-in
start/stop/restart commands, so the web UI will call the "quicker"
version using xml-rpc.
I tried adding a xml-rpc interface by following the instructions
indicated in the website
(http://supervisord.org/xmlrpc.html#rpcinterface-factories). I mimic the
strategy of supervisor-quick
(https://github.com/lxyu/supervisor-quick/blob/master/supervisor_quick.py)
and I use threads to check the process status.
The problem I have is that the call to my xml-rpc interface is not able
to get the target state (RUNNING, STOPPED...) of the process while
waiting in the thread (the most I get for current state is STARTING,
STOPPING). The same problem happens even if I use no thread. It's like
if my code was interfering with the usual supervisor's workflow.
Do somebody has a clue on how to do it? What is wrong with my approach?
(My web interface is developed with django and angular, and offers a
REST API, I think it will be a nice project once finished)
Regards,
Javier
# -*- coding: utf-8 -*-
__version__ = '0.1'
import time
import threading
from supervisor.rpcinterface import SupervisorNamespaceRPCInterface
class QuickNamespaceRPCInterface:
def __init__(self, supervisord, retries=600, delay=0.1, **config):
self.interface = SupervisorNamespaceRPCInterface(supervisord)
self.retries = retries
self.delay = delay
# RPC API methods
def startProcess(self, name):
deferred = self.interface.startProcess(name, wait=False)
deferred()
def _do(name):
success = False
for _ in xrange(self.retries):
current_state =
self.interface.getProcessInfo(name)['statename']
if current_state == 'RUNNING':
success = True
break
else:
time.sleep(self.delay)
return success
t = threading.Thread(target=_do, args=(name,), name=name)
t.start()
t.join()
def startProcessGroup(self, name):
return self.interface.startProcessGroup(name, wait=False)
def startAllProcesses(self):
return self.interface.startAllProcesses(wait=False)
def stopProcess(self, name):
deferred = self.interface.stopProcess(name, wait=False)
deferred()
success = False
for _ in xrange(self.retries):
current_state =
self.interface.getProcessInfo(name)['statename']
if current_state == 'STOPPED':
success = True
break
else:
time.sleep(self.delay)
return success
def stopProcessGroup(self, name):
return self.interface.stopProcessGroup(name, wait=False)
def stopAllProcesses(self):
return self.interface.stopAllProcesses(wait=False)
def make_quick_rpcinterface(supervisord):
return QuickNamespaceRPCInterface(supervisord)
I plan to develop a web user interface for supervisor and share it with
the community (I know that there are some UI out there, but I prefer to
create mine). I want to create my own because I need to integrate the UI
with the "supervisor-quick" extension
(https://pypi.python.org/pypi/supervisor-quick/0.1.3). I have a
production server which takes a lot by using the built-in
start/stop/restart commands, so the web UI will call the "quicker"
version using xml-rpc.
I tried adding a xml-rpc interface by following the instructions
indicated in the website
(http://supervisord.org/xmlrpc.html#rpcinterface-factories). I mimic the
strategy of supervisor-quick
(https://github.com/lxyu/supervisor-quick/blob/master/supervisor_quick.py)
and I use threads to check the process status.
The problem I have is that the call to my xml-rpc interface is not able
to get the target state (RUNNING, STOPPED...) of the process while
waiting in the thread (the most I get for current state is STARTING,
STOPPING). The same problem happens even if I use no thread. It's like
if my code was interfering with the usual supervisor's workflow.
Do somebody has a clue on how to do it? What is wrong with my approach?
(My web interface is developed with django and angular, and offers a
REST API, I think it will be a nice project once finished)
Regards,
Javier
# -*- coding: utf-8 -*-
__version__ = '0.1'
import time
import threading
from supervisor.rpcinterface import SupervisorNamespaceRPCInterface
class QuickNamespaceRPCInterface:
def __init__(self, supervisord, retries=600, delay=0.1, **config):
self.interface = SupervisorNamespaceRPCInterface(supervisord)
self.retries = retries
self.delay = delay
# RPC API methods
def startProcess(self, name):
deferred = self.interface.startProcess(name, wait=False)
deferred()
def _do(name):
success = False
for _ in xrange(self.retries):
current_state =
self.interface.getProcessInfo(name)['statename']
if current_state == 'RUNNING':
success = True
break
else:
time.sleep(self.delay)
return success
t = threading.Thread(target=_do, args=(name,), name=name)
t.start()
t.join()
def startProcessGroup(self, name):
return self.interface.startProcessGroup(name, wait=False)
def startAllProcesses(self):
return self.interface.startAllProcesses(wait=False)
def stopProcess(self, name):
deferred = self.interface.stopProcess(name, wait=False)
deferred()
success = False
for _ in xrange(self.retries):
current_state =
self.interface.getProcessInfo(name)['statename']
if current_state == 'STOPPED':
success = True
break
else:
time.sleep(self.delay)
return success
def stopProcessGroup(self, name):
return self.interface.stopProcessGroup(name, wait=False)
def stopAllProcesses(self):
return self.interface.stopAllProcesses(wait=False)
def make_quick_rpcinterface(supervisord):
return QuickNamespaceRPCInterface(supervisord)