stop python3 example daemonize python daemon

python3 - Comunicándose con un demonio de python corriendo



python daemonize (7)

Escribí una pequeña aplicación de Python que se ejecuta como un demonio. Utiliza hilos y colas.

Estoy buscando enfoques generales para alterar esta aplicación para poder comunicarme con ella mientras se está ejecutando. Sobre todo me gustaría poder controlar su salud.

En pocas palabras, me gustaría poder hacer algo como esto:

python application.py start # launches the daemon

Más tarde, me gustaría poder venir y hacer algo como:

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

Para ser claros, no tengo ningún problema al implementar la sintaxis inspirada en Django. Lo que no tengo idea de cómo hacerlo es enviar señales al proceso de daemonización (inicio), o cómo escribir el daemon para manejar y responder a tales señales.

Como dije anteriormente, estoy buscando enfoques generales. Lo único que puedo ver ahora es decirle al demonio que registre constantemente todo lo que pueda ser necesario en un archivo, pero espero que haya una manera menos complicada de hacerlo.

ACTUALIZACIÓN: Wow, muchas grandes respuestas. Muchas gracias. Creo que veré los enfoques de Pyro y web.py/Werkzeug, ya que Twisted es un poco más de lo que quiero morder en este momento. El siguiente desafío conceptual, supongo, es cómo hablar sobre los hilos de mis trabajadores sin colgarlos.

Gracias de nuevo.


¿Qué hay de tenerlo ejecutando un servidor http?

Parece una locura, pero ejecutar un servidor web simple para administrar su servidor requiere solo unas pocas líneas usando web.py

También puede considerar la creación de un tubo de Unix.


Otro enfoque más: usar Pyro (objetos remotos de Python).

Pyro básicamente le permite publicar instancias de objetos de Python como servicios que se pueden llamar de forma remota. He usado Pyro para el propósito exacto que describe, y encontré que funciona muy bien.

De forma predeterminada, un demonio de servidor Pyro acepta conexiones de todas partes. Para limitar esto, use un validador de conexión (consulte la documentación) o suministre host=''127.0.0.1'' al constructor de Daemon para que solo escuche las conexiones locales.

Código de ejemplo tomado de la documentación de Pyro:

Servidor

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()

Cliente

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")

Otro proyecto similar es RPyC . No he probado RPyC.


Podría asociarlo con Pyro ( http://pythonhosted.org/Pyro4/ ) el objeto remoto de Python. Te permite acceder de forma remota a los objetos de Python. Es fácil de implementar, tiene poca sobrecarga y no es tan invasivo como Twisted.


Suponiendo que está bajo * nix, puede enviar señales a un programa en ejecución con kill desde un shell (y análogos en muchos otros entornos). Para manejarlos desde Python, revise el módulo de signal .


Use werkzeug y haga que su demonio incluya un servidor WSGI basado en HTTP.

Su demonio tiene una colección de pequeñas aplicaciones WSGI para responder con información de estado.

Su cliente simplemente usa urllib2 para realizar solicitudes POST o GET a localhost: somePort. Su cliente y servidor deben acordar el número de puerto (y las URL).

Esto es muy simple de implementar y muy escalable. Agregar nuevos comandos es un ejercicio trivial.

Tenga en cuenta que su demonio no tiene que responder en HTML (aunque a menudo es simple). Nuestros daemons responden a las solicitudes WSGI con objetos de estado codificados en JSON.


Yo usaría trenzado con una tubería con nombre o simplemente abrir un zócalo. Eche un vistazo a los examples servidor y cliente de eco. Necesitará modificar el servidor de eco para buscar alguna cadena que haya pasado el cliente y luego responder con la información solicitada.

Debido a los problemas de subprocesos de Python, tendrá problemas para responder a las solicitudes de información y, al mismo tiempo, continuará haciendo lo que el demonio debe hacer de todos modos. Las técnicas asíncronas u otros procesos son su única opción real.


# 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()

el cliente puede escribirse usando xmlrpclib, verifique el código de ejemplo here .