Dateien -> gleichzeitiges lesen/schreiben verhindern
Michael - Hannover
- php
0 Tom
Hallo !
ich möchte innerhalb eines PHP Scriptes ein Fehlerprotokoll erstellen/speichern
um user aborts zu ignorieren, geschieht dies vorerst vor jeglicher Ausgabe an den Client
mein Problem/Frage
Wie kann ich effektiv und unter Berücksichtigung von XXXXX Prozessen eine "sichere" und korrekte Speicherung der Daten gewährleisten ?
meine eigenen Ansätze dazu (Umsetzung in PHP-Befehle später)
Datei öffnen
Datei versuchen zu sperren (exkl.Lock + LOCK_NB)
WENN erfolgreich
schreiben
Datei schließen
SONST
SOLANGE Sperren nicht erfolgreich (idealerweise max.5 Sekunden(?))
Versuchen zu sperren
WENN erfolgreich
schreiben
Datei schließen
ENDE
ENDE
--> falls das auch nicht geklappt hat, randomized temp.file
anlegen, wobei hier dann wieder zu Beginn des Codings
die Existenz eines solchen Files abgefragt werden müßte
(unique Datei-Endung vorausgesetzt)
dieses wird dann exklusiv geöffnet(fopen($temp.file,"r+"))
/gesperrt (Wartezeit einkalkulieren) Inhalt ins richtige
File portiert,temp.file gelöscht
ENDE
geht das auch effizienter ? und vor allem schneller ?
...wahrscheinlich ist es ab einer best. Menge der laufenden Prozesse nicht mehr möglich, die Datei-Änderung ohne korruption vorzunehmen oder ?
oder GENERELL ein randomized temp.file anlegen und per Cronjobs zusammenführen und danach löschen
Hello,
Du hast ja LOCK_NB schon entdeckt. Das bedeutet also, dass die Lock-Funktion das Locking versucht und wenn sie nicht erfolgreich war, einen Fehler zurückgibt. Du gerätst also nicht ins Timeout des Scriptes.
Wenn man das Locking auf diese Weise durchführt, sollte man es in eine Schleife packen und nach einem erfolglosen Lockversuch 5ms warten. Fünf Versuche dürften reichen, da die Funktion auf LowLevelEbene selber nochmals fünf Versuche in sehr kurzen Abständen vornimmt. Damit es keine Deadlocks gibt, kann man die Wartezeit auch mit jedem Zyklus etwas zufällig verändern. Aber das ist dann schon höhere Mathematik.
Das Öffnen der Datei sollte man jedenfalls nondestructive vornehmen, also mit dem Modus "r+" oder wenn man sich sein kann, dass die Datei vorhanden ist, mit "a+".
Liebe Grüße aus http://www.braunschweig.de
Tom
ich hab vielleicht eine noch effizientere Lösung gefunden
1. Teil
versuchen die (richtige) Error-Datei zu öffnen/sperren
WENN erfolgreich
alle aktuellen randomized.temp lesen, und am Ende der
Error-Datei einfügen
alle aktuellen randomized.temp löschen
ENDE
2. Teil
erzeugen einer Datei mit zufallsgeneriertem Namen randomized.temp
Fehler reinschreiben
fertig
....meiner Meinung nach, müßte das recht performant sein und es
ist gewährleistet, dass immer nur EIN Prozess die originale
Error_Datei bearbeitet
...die Menge der randomized.temp dürfte immer recht gering sein
...keine unnötigen Wartezeiten des Prozesses wegen bestehender Locks
was meint ihr dazu ?
die LOCK_NB Option ist nicht unbedingt das Wahre, wenn ich (fiktiv) zigtausende Prozesse annehme...alle warten...dann macht der Server doch irgendwann dicht (öhh all-inkl.com, wieviele Prozesse erlauben die ? *grins)
Hello,
die eigentliche Bearbeitung einer Datei kann bis zu einer Größe von 1-2MB in weniger als einer Millisekunde stattfinden. Der gesamte Vorgang wird dann mit Allokationszeit auf einem vernüftigen System vielleicht 8ms benötigen. Das bedeutet also, dass rechnerisch ca. 125 Prozesse pro Sekunde abgewickelt werden können.
Für wichtig halte ich eigentlich nur, dass kein Handlewwechsel zwischen fopen und flock und fread und fwrite stattfindet, dass direkt vor jedem Schreibvorgang nochmals gelesen wird und ggf. geprüft, ob es sich noch um die erwarteten Daten handelt (Conflict Counter).
Und dann sofort wieder freigeben.
Liebe Grüße aus http://www.braunschweig.de
Tom