Probleme bei der Entwicklung extererner Python-Skripte

Zombie-Prozesse nach Aufruf von Kommandozeilen-Tools

Bei dem Umsetzen bestimmter Funktionen durch Python-Skripte wurden u.a. auch Tools auf Betriebssystemebene eingesetzt. Diesen Tools wurden beispielsweise Daten über Standardeingabe übergeben und das Ergebnis von Standardausgabe gelesen und in Python weiterverarbeitet. Dabei kam es teilweise zu dem Effekt, dass die Betriebssystemprozesse als sogenannte Zombie-Processes in der Prozess-Tabelle des Betriebssystems verweilten. Die Ursache für diesen Effekt lag höchstwahrscheinlich darin, dass diese Kommandozeilenbefehle mit Funktionen des Python-Modul popen2 abgesetzt wurden (popen2.popen2(), popen2.popen3()). Diese Funktionen erzeugen einen Child-Prozess, an den die Daten über eine Pipe (Standardeingabe) übergeben werden. Dieser verarbeitet die Daten durch das Absetzen des Kommandos und liefert das Ergebnis (hier von Standardausgabe) über eine Pipe an den Vater-Prozess weiter. Bei dem Lesen der Ergebnisdaten wird jedoch nicht daruf geachtet, ob der Bertiebssystemprozess vollständig beendet ist. Ist dies nicht der Fall, wird die Pipe zum Vater frühzeitig geschlossen und der Prozess verweilt als Zombie.

Lösung des Problems:

Expliziter Aufruf der Python-Funktion os.wait(), um sicherzustellen, dass der Child-Prozess (Aufruf des Betriebssystemprozesses) ordnungsgemäß beendet ist bzw. Benutzung der popen()-Methode aus dem Python-Modul os.

Deadlock bei Aufruf von Kommandozeilen-Tools mittels popen.popen*()

Bei der Benutzung des popen2-Moduls ist eine weitere Störung aufgetreten. Wurde mittels dieses Funktionsaufrufes ein Kommandozeilen-Tool aufgerufen und über Standardeingabe eine größere Datenmenge übergeben, so blockierte der Prozess. Ursache dafür ist wahrscheinlich die vollständige Belegung des Buffers für die Standardeingabe. Es wurden Daten über Standardeingabe übergeben, die mehr Buffer-Speicher benötigten als für die Standardeingabe reserviert gewesen ist. Somit wartete der Vater-Prozess auf Ergebnisdaten, wobei der Kind-Prozess noch auf Eingabedaten über Standardeingabe wartete (da noch kein EOF erhalten).

Lösung des Problems:

Nach Recherche im Internet wurde ein Skript-Fragment gefunden, welches die Aufgabe von popen2.popen2() nicht mittels 2 Prozessen, sondern mittels 3 Prozessen realisiert und somit der Deadlock vermieden wird. Diese Funktion (rwpopen) wurde im Python-Skript libRotate.py implementiert.

Probleme bei Aufruf von tiff2ps aus Python

Bei einem der Konvertierungsschritte vom tif-File zum PDF-Dokument wird das Tool tiff2ps genutzt. Dieses Tool ermöglicht per Parameter-Angabe die Erzeugung von Postscript-Dateien unterschiedlichen Postscript-Levels. Bei dem Aufruf von tiff2ps mit dem Parameter -2 (Erzeugung von PS Level 2) schlägt die Konvertierung fehl (Unrecoverable Ghostscript error).

Lösung des Problems:

Parameter -2 wird bei dem Aufruf von tiff2ps weggelassen.

Browser-Refresh vor Beendigung der Rotate-Methode

Beim Rotieren eines Faxes kam es anfänglich zu vorzeitigen Refreshs der jeweiligen Seite im Browser. Das Problem lag darin, dass pro zu drehendem Objekt ein Thread gestartet wurde. Sobald alle Threads abgesetzt waren, wurde die Main-Methode beendet, und es erfolgte ein Refresh im Browser. Die Objekte waren zu diesem Zeitpunkt noch nicht vollständig bearbeitet.

Lösung des Problems:

Ersetzen der Threads durch normale Methoden-Aufrufe. Aufruf der Methode ZCacheable_invalidate() für jedes geänderte Zope-Objekt vor dem Update der Objektdaten innerhalb von Zope.

Fehlerbehandlung bei korruptem GZ-Archiv innerhalb eines Faxordners

Beim Rotieren und Wiederherstellen eines Faxes werden u.a. Daten aus einem GZ-Archiv gelesen. Dazu wird das Python-Modul gzip verwendet, welches gzip-kompatible Archive liest und erstellt. Ist eines dieser Archive nicht gzip-kompatible bzw. korrupt, so tritt ein IOError auf, der nicht abgefangen werden kann.