web-dev-qa-db-fra.com

Communiquer avec une exécution python démon

J'ai écrit un petit Python application qui fonctionne comme un démon. Il utilise le filetage et les files d'attente.

Je cherche des approches générales pour modifier cette application afin que je puisse communiquer avec elle pendant son fonctionnement. La plupart du temps, j'aimerais pouvoir surveiller sa santé.

En bref, j'aimerais pouvoir faire quelque chose comme ça:

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 à mettre en œuvre la syntaxe inspirée de Django. Ce que je n'ai aucune idée de comment faire est d'envoyer des signaux au processus démonisé (démarrage) ou comment écrire le démon pour gérer et répondre à ces signaux.

Comme je l'ai dit ci-dessus, je cherche des approches générales. Le seul que je puisse voir en ce moment, c'est dire que le démon enregistre constamment tout ce qui pourrait être nécessaire dans un fichier, mais j'espère qu'il y a une façon moins désordonnée d'y aller.

Mise à jour : wow, beaucoup de bonnes réponses. Merci beaucoup. Je pense que je vais regarder à la fois pyro et les approches web.py/werkzeug, puisque torsadée est un peu plus que je ne veux mordre à ce stade. Je suppose que le prochain concept conceptuel, je suppose, est de savoir comment parler à mes fils de travail sans les suspendre.

Merci encore.

52
hanksims

Encore une autre approche: utilisation pyro (objets de télécommande Python).

Le pyro vous permet essentiellement de publier Python les instances d'objet comme des services qui peuvent être appelés à distance. J'ai utilisé PYRO pour le but exact que vous décrivez et j'ai trouvé cela très bien fonctionner.

Par défaut, un démon de serveur de pyro accepte les connexions de partout. Pour limiter cela, utilisez un validateur de connexion (voir la documentation) ou l'approvisionnement Host='127.0.0.1' au constructeur Daemon pour écouter uniquement les connexions locales.

Exemple de code pris de la documentation pyro:

serveur

[.____] Importer pyro.core [.____] 
 Classe Jokegen (pyro.core.Objbase): 
 def __init __ (auto): [.____] .__ init __ (auto-) [.____] def blague (auto, nom): 
 Retour "Désolé" + nom + ", je ne connais aucune blague." [.____] Pyro.core.inditifverver () 
 Démon = pyro.core.daemon () [) [ Imprimer "Le démon fonctionne sur le port:", Daemon.port [.____] Imprimer "L'Uri de l'objet est:", Uri [.____] [.____] Daemon.Requestloop () [.____]

Client

[.____] importer pyro.core 
 
 # Vous devez changer l'URI ci-dessous pour correspondre à votre propre hôte/port. [.____] blagues = pyro.core.getproxyforri ("Pyroloc : // localhost: 7766/Jokegen ") 
 
 Imprimer des blagues.joke (" Irmen ") [.____]

Un autre projet similaire est RPYC . Je n'ai pas essayé RCYC.

35
codeape

Utilisez WERKZEUG et faites que votre démon comprend un serveur WSGI basé sur HTTP.

Votre démon a une collection de petites applications WSGI pour répondre aux informations de statut.

Votre client utilise simplement Urllib2 à faire POST ou obtenir des demandes à localhost: Certainport. Votre client et votre serveur doivent être d'accord sur le numéro de port (et l'URL).

Ceci est très simple à mettre en œuvre et très évolutif. L'ajout de nouvelles commandes est un exercice trivial.

Notez que votre démon n'a pas à répondre en HTML (c'est souvent simple, cependant). Nos daemons répondent aux demandes WSGI avec des objets d'état codés JSON.

16
S.Lott

J'utiliserais tordu avec un tuyau nommé ou simplement ouvrir une prise. Jetez un coup d'œil au serveur d'écho et au client exemples . Vous auriez besoin de modifier le serveur ECHO pour rechercher une chaîne passée par le client, puis répondez avec toutes les informations demandées.

En raison des problèmes de filetage de Python que vous allez avoir du mal à répondre aux demandes d'informations tout en continuant à faire ce que le démon est censé faire de toute façon. Techniques asynchrones ou Forking ANDERNES PROCESSUS sont votre seule option réelle.

9
MrEvil
# 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 __== '__main__':
    r = MyServer()
    reactor.listenTCP(8080, Server.Site(r))
    reactor.run()

le client peut être écrit à l'aide de XMLRPCLIB, vérifiez le code d'exemple ici .

7
Badri

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

5
MarkusQ

Vous pouvez l'associer à Pyro (- http://pythonhosted.org/pyro4/ ) =Python objet distant. Il vous permet d'accéder à distance python Objets. Il est facilement à mettre en œuvre, a de faibles frais généraux et n'est pas aussi invasif que tordé.

4
directedition