2009-03-20 2 views
0

Ein Webdienst ist so konfiguriert, dass einige seiner Daten beim Empfang eines USR1-Signals verfügbar gemacht werden. Das Signal wird von einem xinetd-Server gesendet, wenn es eine Anfrage von einem entfernten Client empfängt, z. nc myserver 50666. Wenn der Webserver das USR1-Signal empfängt, öffnet er eine dedizierte Fifo-Pipe, schreibt seine Daten in die Pipe und schließt dann die Pipe. In der Zwischenzeit liest der xinetd-Server die Pipe und leitet sie an den Remote-Client weiter.Wie debugge ich ein seltsames Threaded Open Fifo Problem?

In den meisten Fällen funktionieren sie gut, aber gelegentlich, aus irgendeinem Grund, erhält der Client dup Datensätze. Aus dem Protokoll scheint es, als ob die Pipe nicht ordnungsgemäß geschlossen wurde und der Cache übrig geblieben ist. Beim nächsten Mal werden sowohl der vorherige als auch der aktuelle an den Client gesendet. Das Problem ist, dass es nicht ständig passiert, wenn man versucht, sich zu reproduzieren, unglücklicherweise konnte ich nicht einmal reproduzieren.

Im folgenden sind die einfachen Schnipsel den Vorgang zu demonstrieren:

Der Webserver: (webserver.py)

def SendStream(data, pipe): 
    try: 
    for i in data: 
     pipe.write(i + '\n') 
     pipe.flush() 
    finally: 
     pipe.close() 

def Serve(): 
    threading.Thread(target=SendStream, args=(data, pipe)).start() 

xinetd.d Server: (spitter.py)

def Serve(): 
    if not os.path.exists(PIPE_FILE): 
    os.mkfifo(PIPE_FILE) 
    os.kill(server_pid, signal.SIGUSR1) 
    for i in open(PIPE_FILE): 
    print i, 

Was genau ist passiert, um die dup? Wie man es auslöst? Die aktuelle Lösung Ich lehne die Pipe-Datei auf und stelle sie jedes Mal neu her, um irgendwelche Reste zu vermeiden, aber ich weiß nicht, ob das eine richtige Lösung ist.

Antwort

0

Wenn Sie zwei Kopien von spliter.py gleichzeitig ausführen, wird es Probleme geben und fast alles, was Ihnen passiert, ist legal. Versuchen, einen Prozess-ID-Wert zu Zugabe von webserver.py, dh:

pipe.write (str (os.getpid()) + i + '\ n')

dass beleuchte werden könnten.

+0

Es gibt ein paar Probleme mit dieser Lösung, wie ich denken kann: 1. Es ändert die Ausgabe. 2. Es gibt keine Race-Condition unter dem aktuellen Design. Der Kunde ist eine Zeitschnittmaschine. (alle paar Minuten zieht es einmal und es gibt noch keine anderen Clients) – jimx

+0

Beide Probleme sind für das Debugging irrelevant. Tatsächlich würde ich dazu Zeitstempel hinzufügen und dann am Ende des Lesers einen weiteren Zeitstempel hinzufügen. Gesundheitschecks sind wichtig. – Rhamphoryncus

0

Es gibt nicht genug, um hier zu debuggen. Sie zeigen nicht, wie der Server Signale verarbeitet oder die Pipe öffnet.

Wenn möglich, würde ich empfehlen, keine Signale zu verwenden. Sie sind in C haarig genug, vergiss nichts mit Pythons eigenen Besonderheiten.

+0

Was wäre hier eine bessere Lösung aus Ihrer Empfehlung? Im Grunde brauche ich einen effizienten IPC-Mechanismus, um Daten zwischen zwei Prozessen zu teilen. Vielen Dank! – jimx

+0

Unix-Domain-Sockets sind die flexibelsten für rein lokale Nutzung. Sie können Dateideskriptoren sogar übergeben, wenn Sie müssen. Andernfalls verwenden Sie TCP auf localhost. – Rhamphoryncus

0

Also das eigentliche Problem ist, dass es mehrere Clients gibt. Der Server wurde von anderen unbekannten Clients abgefragt/missbraucht, die ursprünglich nicht mit den Kunden vereinbart wurden und sicher sind, dass sie unter dem aktuellen Design brechen werden. Ein Fix wurde bereitgestellt, um das Problem zu beheben. Andys Verdacht stimmt also. Danke Leute!