Discussion:
[Supervisor-users] supervisor-quick with xml-rpc
Javier Matos Odut
2015-08-02 23:52:08 UTC
Permalink
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)

Loading...