Domanda

Ho scritto una piccola applicazione Python che funziona come un demone. Utilizza thread e code.

Sto cercando approcci generali per modificare questa applicazione in modo da poter comunicare con essa mentre è in esecuzione. Principalmente vorrei essere in grado di monitorare la sua salute.

In breve, vorrei poter fare qualcosa del genere:

python application.py start  # launches the daemon

In seguito, vorrei poter venire e fare qualcosa del tipo:

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

Per essere chiari, non ho alcun problema ad implementare la sintassi ispirata a Django. Quello che non ho idea di come fare è inviare segnali al processo daemonizzato (start) o come scrivere il demone per gestire e rispondere a tali segnali.

Come ho detto sopra, sto cercando approcci generali. L'unico che posso vedere in questo momento è dire al demone di registrare costantemente tutto ciò che potrebbe essere necessario in un file, ma spero che ci sia un modo meno disordinato per farlo.

AGGIORNAMENTO: Caspita, molte ottime risposte. Grazie mille. Penso che esaminerò entrambi gli approcci di Pyro e web.py/Werkzeug, dal momento che Twisted è un po 'più di quello che voglio mordere a questo punto. La prossima sfida concettuale, suppongo, è come parlare con i miei thread di lavoro senza riagganciarli.

Grazie ancora.

È stato utile?

Soluzione

Che ne dici di far funzionare un server http?

Sembra folle, ma con un semplice server web per amministrare il tuo il server richiede solo poche righe usando web.py

Puoi anche prendere in considerazione la creazione di una pipe unix.

Altri suggerimenti

Ancora un altro approccio: usa Pyro (oggetti remoti Python).

Pyro consente sostanzialmente di pubblicare istanze di oggetti Python come servizi che possono essere chiamati in remoto. Ho usato Pyro per lo scopo esatto che descrivi e ho trovato che funziona molto bene.

Per impostazione predefinita, un demone del server Pyro accetta connessioni da qualsiasi luogo. Per limitare ciò, utilizzare un validatore di connessione (consultare la documentazione) o fornire host = '127.0.0.1' al costruttore Daemon per ascoltare solo le connessioni locali.

Esempio di codice tratto dalla documentazione di Pyro:

Server

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 altro progetto simile è RPyC . Non ho provato RPyC.

Usa werkzeug e fai in modo che il tuo demone includa un server WSGI basato su HTTP.

Il tuo demone ha una raccolta di piccole app WSGI per rispondere con le informazioni sullo stato.

Il tuo client usa semplicemente urllib2 per effettuare richieste POST o GET a localhost: somePort. Il client e il server devono concordare il numero di porta (e l'URL).

Questo è molto semplice da implementare e molto scalabile. L'aggiunta di nuovi comandi è un esercizio banale.

Nota che il tuo demone non deve rispondere in HTML (spesso è semplice). I nostri demoni rispondono alle richieste WSGI con oggetti di stato con codifica JSON.

Userei attorcigliato con una pipa denominata o semplicemente aprire una presa. Dai un'occhiata al server e al client echo esempi . Dovresti modificare il server echo per verificare la presenza di una stringa passata dal client e quindi rispondere con qualsiasi informazione richiesta.

A causa dei problemi di threading di Python avrai problemi a rispondere alle richieste di informazioni mentre continuerai a fare qualunque cosa il demone debba fare comunque. Le tecniche asincrone o il fork di altri processi sono la tua unica vera opzione.

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

il client può essere scritto usando xmlrpclib, controllare il codice di esempio qui .

Supponendo che tu sia sotto * nix, puoi inviare segnali a un programma in esecuzione con kill da una shell (e analoghi in molti altri ambienti). Per gestirli da Python, controlla il modulo signal .

Potresti associarlo a Pyro ( http://pythonhosted.org/Pyro4/ ) the Python Oggetto remoto. Ti consente di accedere in remoto agli oggetti Python. È facile da implementare, ha bassi costi generali e non è invasivo come Twisted.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top