Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Lysander schrieb: Hui... du hast mal das OpenBook von Galileo gelesen, richtig? Vergiss den mal schön, anders als in C++ sollte man den Destruktor in Python meiden.
kp woher ich den hab - glaube google. aber das openbook wars nicht 😛 warum sollte man den deiner meinung nach in python meiden und was sollte man stattdessen verwenden? wegen race condition kam mir noch ne idee (die prüfung ob die id überhaupt gültig ist war jetzt mal schon früher und ist positiv ausgefallen - andernfalls wären wir in einem anderen zweig des konstruktors:
| try:
verschiebe sid.dat zu sid.lck
except datei nicht vorhanden:
warten wie oben beschrieben
else:
daten lesen aus sid.lck
|
(datei nicht vorhanden bedeutet - da nach voraussetzung entweder dat oder lck existieren - dass die session gesperrt ist und die lck vorhanden ist sollte gehen, sofern das verschieben aka umbenennen atomar ist (was ich nicht genau weiß)....
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Glocke schrieb: kp woher ich den hab - glaube google. aber das openbook wars nicht 😛 warum sollte man den deiner meinung nach in python meiden und was sollte man stattdessen verwenden?
Lies es bei BlackJacks Kritik am OpenBook nach: http://bj.spline.de/python_openbook.html#destruktor
wegen race condition kam mir noch ne idee (die prüfung ob die id überhaupt gültig ist war jetzt mal schon früher und ist positiv ausgefallen - andernfalls wären wir in einem anderen zweig des konstruktors:
| try:
verschiebe sid.dat zu sid.lck
except: datei nicht vorhanden
warten wie oben beschrieben
else:
daten lesen aus sid.lck
|
sollte gehen, sofern das verschieben aka umbenennen atomar ist (was ich nicht genau weiß)....
Genau das hängt ja vom OS ab - auch das findet man durch das Studium der werkzeug-Lösung heraus. Wenn man per mkstemp() eine temporäre Datei erzeugt und diese dann umbennen will, tritt ja gerade dieses Problem auf. (und mkstemp an sich ist ja laut Doku garantiert atomar)
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
bzgl. destruktor werde ich das speichern in eine save() methode verlegen und den destruktor aus dem quellcode entfernen. danke für den link!! wegen os.rename() werde ich mich belesen.
|
DasIch
Anmeldungsdatum: 2. November 2005
Beiträge: 1130
|
Glocke schrieb: Zunächst prüfe ich mittels os.path.isfile(filename) ob die lock-file existiert. [...]wenn die lock-file dann mal weg ist wird sofort eine neue lock-file erstellt[...]
Wenn os.path.isfile(filename) False zurückgibt und du danach erst eine Datei erstellst, kann es sein das zwischen dem Check und dem erstellen der Datei, ein anderer Prozess die Datei erstellt. Schau dir an wie Werkzeug das macht. Die Implementation funktioniert und alles was sie tut und wie sie es tut hat sehr gute Gründe.
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Lysander und ich waren beim Umbenennen der .dat auf .lck stehengeblieben. Wenn dies atomar geschieht, wird die Session race condition sicher gelockt (für mein Skript). os.rename() If successful, the renaming will be an atomic operation (this is a POSIX requirement).
Denke damit dürfte sich das Problem erledigt haben, oder?
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Glocke schrieb: os.rename() If successful, the renaming will be an atomic operation (this is a POSIX requirement).
Denke damit dürfte sich das Problem erledigt haben, oder?
Auf POSIX kompatiblen Systemen ja. Auch das findet sich in werkzeug. Ich habe in meinem Beitrag bereits darauf Bezug genommen. Du musst halt im werkzeug Code nachgucken, wie das rename() dort durch Monkey-Patching bei NT like Systemen repariert wird.
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Das skript wird eh nur auf POSIX-kompatiblen Linux-Servern zum Einsatz kommen. Unter dieser Restriktion sollten also keine weiteren Probleme auftreten, oder?
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Glocke schrieb: Das skript wird eh nur auf POSIX-kompatiblen Linux-Servern zum Einsatz kommen. Unter dieser Restriktion sollten also keine weiteren Probleme auftreten, oder?
Kommt dann eben noch drauf an, wie Du die Dateien erzeugst. Ansonsten: ja.
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
naja eine neue session erstellt die file mittels open. wobei ich ahne dass das wiederum zu race conditions führen kann ....
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Glocke schrieb: naja eine neue session erstellt die file mittels open, write("") und close. wobei ich ahne dass das wiederum zu race conditions führen kann ....
was man ja durch das Nutzen von mkstemp() umgehen kann... 😉 Genau diese Erkenntnis kann man aus dem Code von werkzeug gewinnen 😎
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Lysander schrieb: Genau diese Erkenntnis kann man aus dem Code von werkzeug gewinnen 😎
oder durch das lesen der python doc (was ich eben gemacht habe).
ich schaffe es aber nicht die file mit korrektem namen zu erstellen - ich habe ständig irgendwelche anderen buchstaben dahinter. | >>> import tempfile
>>> tempfile.mkstemp(prefix="Beispiel", suffix=".dat", dir="/home/glocke/Desktop")
(3, '/home/glocke/Desktop/Beispiel4An6RG.dat')
|
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Glocke schrieb: Lysander schrieb: Genau diese Erkenntnis kann man aus dem Code von werkzeug gewinnen 😎
oder durch das lesen der python doc (was ich eben gemacht habe).
Ok, ich Kombination eben - oder wie bist Du sonst auf mkstemp() gekommen?
ich schaffe es aber nicht die file mit korrektem namen zu erstellen - ich habe ständig irgendwelche anderen buchstaben dahinter. | >>> import tempfile
>>> tempfile.mkstemp(prefix="Beispiel", suffix=".dat", dir="/home/glocke/Desktop")
(3, '/home/glocke/Desktop/Beispiel4An6RG.dat')
|
Was meinst Du mit "dahinter"? Sieht doch gut aus!
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Lysander schrieb: Glocke schrieb: oder durch das lesen der python doc (was ich eben gemacht habe).
Ok, ich Kombination eben - oder wie bist Du sonst auf mkstemp() gekommen?
python doc - gegoogelt nach "python create file atomic" etc.
| >>> import tempfile
>>> tempfile.mkstemp(prefix="Beispiel", suffix=".dat", dir="/home/glocke/Desktop")
(3, '/home/glocke/Desktop/Beispiel4An6RG.dat')
|
Was meinst Du mit "dahinter"? Sieht doch gut aus!
fast: die file sollte /home/glocke/Desktop/Beispiel.dat heißen. ich will dann mit der sid als prefix erzeugen. und da beim prüfen ob die sid vergeben ist geguckt wird ob eine datei namens <sid>.dat oder <sid>.lck existiert, stört das teil hinter dem prefix.
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Glocke schrieb: Lysander schrieb: Glocke schrieb: oder durch das lesen der python doc (was ich eben gemacht habe).
Ok, ich Kombination eben - oder wie bist Du sonst auf mkstemp() gekommen?
python doc - gegoogelt nach "python create file atomic" etc.
Naja, es wurde in diesem Thread ja auch schon zig mal erwähnt...
| >>> import tempfile
>>> tempfile.mkstemp(prefix="Beispiel", suffix=".dat", dir="/home/glocke/Desktop")
(3, '/home/glocke/Desktop/Beispiel4An6RG.dat')
|
Was meinst Du mit "dahinter"? Sieht doch gut aus!
fast: die file sollte /home/glocke/Desktop/Beispiel.dat heißen. ich will dann mit der sid als prefix erzeugen. und da beim prüfen ob die sid vergeben ist geguckt wird ob eine datei namens <sid>.dat oder <sid>.lck existiert, stört das teil hinter dem prefix.
Na das ist eben ja der Clou eines Temp-Files - es soll ja einzigartig sein. Daher musst Du es ja nach dem Anlegen entsprechend umbenennen mit os.rename(). Auch das hatten wir ja nun schon. Letztlich ist das eben genau die Idee hinter dem Code in Werkzeug! Ich poste hier noch mal den Schnipsel:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | # man beachte das rename nicht direkt aus os importiert wird.
from werkzeug.posixemulation import rename
def save(self, session):
fn = self.get_session_filename(session.sid)
# hier wird eben atomar eine Datei erzeugt
fd, tmp = tempfile.mkstemp(suffix=_fs_transaction_suffix,
dir=self.path)
f = os.fdopen(fd, 'wb')
try:
dump(dict(session), f, HIGHEST_PROTOCOL)
finally:
f.close()
try:
# und hier wird das ganze dann passend umbenannt.
# wenn Du oben guckst, siehst Du dass rename() intern definiert ist
# s. o.
rename(tmp, fn)
os.chmod(fn, self.mode)
except (IOError, OSError):
pass
|
Link Du kannst Dir den MonkeyPatch in dem Modul ja mal angucken. Man erkennt dort, dass er nur im Falle von NT basierten OS benötigt wird. So, ich hoffe Du erkennst nun den Sinn dahinter, dass wir bereits auf Seite eins nach wenigen Posts auf werkzeug hingewiesen haben 😉
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
den sinn habe ich schon lange erkannt, aber mir ging es um das (mit eurer hilfe) eigene herangehen an das problem. code kopieren wäre das einfachste gewesen, richtig. dann hätte ich keine probleme und wir wären nicht schon auf seite 3. aber mir gehts halt darum selber mir gedanken zu machen - egal ob ich zum schluss bei was sehr ähnlichen rauskomme oder nicht. es ist einfach der wille nach erfahrungssammlung bzgl. problemlösung. das problem was sich mir stellt (vllt auch nur denkfehler): meine sid ist x, ich erstelle eine tempfile mit xy.dat ein anderer prozess hat auch die sid x und erstellt xz.dat jetzt bin ich vor dem anderen prozess mit speichern und umbenennen dran und habe meine x.dat fertig oder es dauert mein prozess warum auch immer länger und der andere prozess speichert und benennt als erstes um dann heißt seine file x.dat jetzt komm ich und speichere meine daten und benenne um. rename überschreibt ohne rückfrage. die alte x.dat wird mit der neuen x.dat überschrieben - daten des zweiten prozesses weg.
nicht schön oder habe ich da nen denkfehler
|