Question

J'ai écrit une petite application Python qui s'exécute en tant que démon. Il utilise des threads et des files d'attente.

Je recherche des approches générales pour modifier cette application afin de pouvoir communiquer avec elle pendant son exécution. J'aimerais surtout pouvoir surveiller sa santé.

En un mot, j'aimerais pouvoir faire quelque chose comme ceci:

python application.py start  # launches the daemon

Plus tard, j'aimerais pouvoir venir et faire quelque chose comme:

python application.py check_queue_size  # return info from the daemonized process

Pour être clair, je n'ai aucun problème à implémenter la syntaxe inspirée de Django. Ce que je ne sais pas, c’est d’envoyer des signaux au processus démonisé (démarrage) ou d’écrire le démon pour gérer ces signaux et y répondre.

Comme je l’ai dit plus haut, je recherche des approches générales. Le seul moyen que je connaisse pour le moment est de dire au démon de consigner constamment tout ce qui peut être nécessaire pour un fichier, mais j'espère qu'il y a une façon moins compliquée de s'y prendre.

MISE À JOUR: Wow, beaucoup de bonnes réponses. Merci beaucoup. Je pense que je vais regarder Pyro et les approches web.py/Werkzeug, puisque Twisted est un peu plus que ce que je veux dire à ce stade-ci. Le prochain défi conceptuel, je suppose, consiste à savoir comment parler aux discussions de mes travailleurs sans les suspendre.

Merci encore.

Était-ce utile?

La solution

Qu'en est-il de le faire fonctionner sur un serveur http?

Cela semble fou, mais utiliser un simple serveur Web pour administrer votre le serveur nécessite seulement quelques lignes avec web.py

Vous pouvez également envisager de créer un pipe Unix.

Autres conseils

Encore une autre approche: utilisez Pyro (objets à distance Python).

Pyro vous permet en principe de publier des instances d'objet Python en tant que services pouvant être appelés à distance. J'ai utilisé Pyro pour le but exact que vous décrivez et je l'ai trouvé très bien.

Par défaut, un démon serveur Pyro accepte les connexions de partout. Pour limiter cela, utilisez un validateur de connexion (voir la documentation) ou fournissez host = '127.0.0.1' au constructeur Daemon pour n'écouter que les connexions locales.

Exemple de code tiré de la documentation Pyro:

Serveur

import Pyro.core

class JokeGen(Pyro.core.ObjBase):
        def __init__(self):
                Pyro.core.ObjBase.__init__(self)
        def joke(self, name):
                return "Sorry "+name+", I don't know any jokes."

Pyro.core.initServer()
daemon=Pyro.core.Daemon()
uri=daemon.connect(JokeGen(),"jokegen")

print "The daemon runs on port:",daemon.port
print "The object's uri is:",uri

daemon.requestLoop()

Client

import Pyro.core

# you have to change the URI below to match your own host/port.
jokes = Pyro.core.getProxyForURI("PYROLOC://localhost:7766/jokegen")

print jokes.joke("Irmen")

Un autre projet similaire est RPyC . Je n'ai pas essayé le RPyC.

Utilisez werkzeug et demandez à votre démon d'inclure un serveur WSGI basé sur HTTP.

Votre démon dispose d'un ensemble de petites applications WSGI pour répondre avec des informations sur l'état.

Votre client utilise simplement urllib2 pour envoyer des requêtes POST ou GET à localhost: somePort. Votre client et votre serveur doivent convenir du numéro de port (et de l’URL).

C’est très simple à mettre en œuvre et très évolutif. Ajouter de nouvelles commandes est un exercice trivial.

Notez que votre démon n'a pas à répondre en HTML (bien que ce soit souvent simple). Nos démons répondent aux requêtes WSGI avec des objets d'état codés JSON.

Je voudrais utiliser tordu avec un tuyau nommé ou tout simplement ouvrir un socket. Jetez un coup d’œil aux exemples du serveur et du serveur d'écho. Vous devrez modifier le serveur d'écho pour vérifier la présence d'une chaîne transmise par le client, puis répondre avec les informations demandées.

En raison des problèmes de threading de Python, vous aurez des difficultés à répondre aux demandes d’informations tout en continuant à exécuter les tâches que le démon est censé faire. Les techniques asynchrones ou le recours à un autre processus sont votre seule véritable option.

# your server

from twisted.web import xmlrpc, server
from twisted.internet import reactor

class MyServer(xmlrpc.XMLRPC):

    def xmlrpc_monitor(self, params):        
        return server_related_info

if __name__ == '__main__':
    r = MyServer()
    reactor.listenTCP(8080, Server.Site(r))
    reactor.run()

client peut être écrit en utilisant xmlrpclib, consultez l'exemple de code ici .

En supposant que vous êtes sous * nix, vous pouvez envoyer des signaux à un programme en cours d'exécution avec kill à partir d'un shell (et des analogues dans de nombreux autres environnements). Pour les gérer depuis python, consultez le module signal .

Vous pouvez l'associer à Pyro ( http://pythonhosted.org/Pyro4/ ) le Python. Objet distant. Il vous permet d’accéder à distance aux objets python. Il est facile à mettre en œuvre, ses frais généraux sont minimes et il n’est pas aussi invasif que Twisted.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top