Hallo,
Ein Posting vorher sah es fuer mich noch so aus,
wie wenn Du vorschlaegst, den Wert eines Pointers
(auf int gecastet) zur Bildung eines system-
global eindeutigen Dateinamens heranzuziehen.
Das geht natürlich nicht. Der wäre dann nur lokal
und nur at Runtime einmalig.
der Dateiname muß auch nur während der Laufzeit des
Programms eindeutig sein - das ist ja eine temporäre
Datei, die anschließend auf ihren endgültigen Namen
innerhalb des Cache umbenannt wird.
Ja, das ist bekannt. Wollte nur darauf hinweisen, das _global_ eindeutig identifizierbare Namen ein kaum lösbares Problem darstellen.
War wohl etwas ungenauer formuliert als sowieso schon beabsichtigt ;-)
Wobei wir das Umbenennen als "hinreichend unteilbar"
angenommen haben - zumal es egal wäre, wenn ein zwei-
ter Prozeß das Ergebnis eines vorherigen überschreibt:
Stimmt auch mal wieder. Habe ich jetzt nicht bedacht.
Sollte sich über einen Index eigentlich bequem lösen lassen.
Aber ob sich das rechnen würde wage ich dann doch arg zu bezweifeln.
Also lieber die eine oder andere Überschreibung riskieren.
Bei der Komprimierung werden ja nicht semantisch ver-
schiedene Ergebnisse heraus kommen.
Wollen's hoffen ;-)
Insofern erfüllt die $PID semantisch betrachtet genau
das, was wir erreichen wollten ... es könnte jedoch
durchaus sein, daß ein absoluter (!) Adreßraumpointer
dieselben Eigenschaften könnte. Ein relativer (bei
einem Betriebssystem mit virtuellem Adreßraum) dagegen
würde wohl nicht reichen, denke ich.
Nein, noch nicht einmal ein absoluter.
Es wird aber sowieso umbenannt. Der endgültige Name folgt einer bekannten Gesetzgebung (sonst könnte er ja nicht gefunden werde, gelle? ;-).
Warum also wird überhaupt ein derart streng definierter Identifikator gesucht?
Alles, was nicht dem endgültigem Schema entspricht, ist also schonmal eine temporäre Datei. Der Name der temporären Datei, die geschrieben werden soll, ist auch innerhalb des jeweiligen Prozesses bekannt.
Warum also nicht mittels Registern eine Nummer verarbeiten und die anhängen?
Bei Rückgabe von EEXIST wird halt einfach um 123 incriminiert.
Auf EEXIST muß sowieso geprüft werden, da auch eine PID im Laufe eines Serverlebens mehrfach (halt nur nie gleichzeitig) auftauchen kann.
(Wenn man mal davon absieht, das Überschreiben akzeptabel sei)
Allerdings habe ich mich da gerade völlig verwurschtelt. Ich wollte doch die Zusammenbastelei vermeiden. Du hast mich hier völlig aus dem Konzept gebracht! ;-)
Gut: das ganze läuft wie folgt (bzw sollte so funktionieren ;-):
gzip_cncc bekommt einen Dateinamen der übertragen werden soll.
Der wird geprüft, ob er überhaupt vorhanden ist. if false -> 404
Wenn tatsächlich vorhanden, wird geprüft, ob evt schon eine komprimierte Version vorhanden ist if true -> send cached-file
Wenn keine da ist, wird der Kompressionsmechanismus angeworfen.
Temporäre Datei erzeugt. Angeforderte Datei komprimiert in das Tempfile
Umbenennen des Tempfiles in ein reguläres Cachefile nach Muster.
Name des Tempfiles = Cachefile + lokaler Identifikator (PID)
Name des Cachefiles = Cache-Pfad + Originaldateiname + ".gz"
Mir ist immer noch nicht ganz eingängig, warum beim Tempfile ein _ein_deutiger Identifikator da sein muß.
Besser wäre es doch, in einem Temdir die Dateien mit richtigem und vollständigem Namen abzulegen, sodaß ein EEXIST die Mehrfachüberschreibung im Keime erstickt.
(In dem Falle -> send-orig-file für alle, die ein EEXISTS bei der Komprimierung erwischt.)
Also komprimiert immer nur der erste gzip_cncc Prozess die Datei und belastet den Prozessor und das Dateisystem. Der Rest arbeitet ganz normal.
Ich glaube, daß so die Zeit bis zum erstem möglichem Cachezugriff deutlich verkürzt wird.
Denn wenn eine Datei noch nicht im Cache liegt, wird sie von jedem gzip_cncc Prozess in die Mangel genommen, der die Anfrage auf die gleiche Datei bekommt solange sie noch nicht im Cache auftaucht.
Da er die URIs abbildet, also im Cache Verzeichnis
am Ende der Verzeichnisbaum abgebildet ist, sind die
Dateinamen eh eindeutig (sind ja erstens nur
statische Seiten und zweitens kann das durchaus bei
komplizierten Pfadumbauten seitens des Apachen auch
in die Hose gehen ;-).
Das habe ich jetzt nicht wirklich verstanden.
Nicht nur kompliziert Pfadumbauten, auch verzwickte Grammatik ;-)
Aber ich kann Dich beruhigen, Du hast das Problem durchaus erkannt.
Der Cache-Baum repräsentiert _nicht_ den Dateibaum,
sondern den URI-Baum - es kann also bei entsprechenden
URL-Mappings durchaus vorkommen, daß dasselbe Dokument
mehrfach im Cache herumliegt.
Ich hatte eher den Umstand im Auge, das evt derselbe Datei_name_ mehrfach in den Cache geschickt wird ;-)
Das kommt m. E. aber
selten vor - seltener jedenfalls, als daß _überhaupt_
Mappings verwendet werden. Daß der URL-Raum auf
mehrere Datei-Teilbäume verteilt sein kann, damit
wollte ich fertig werden können.
Da sehe ich auch gar kein Problem drin.
Und ich wollte _eine_ Wurzel des Cache-Baums haben,
ohne dafür die Wurzel des gesamten Verzeichnisbaums zu
verwenden ... das wäre auch gegangen, hätte aber
längere Pfadnamen zur Folge gehabt.
Hätte auch keine große Rolle gespielt. Die maximal möglichen Dateinamen (incl Pfad) sind bei den jetzigen Systemen auf 4096 begrenzt. Das ist bei den gängigen Architekturen genau ein Page. Verlahmung (schönes Wort, leider nichtz von mir ;-) durch Speicherfragmentierung sollte also kein großes Problem darstellen.
FILENAME_MAX enthält die entsprechende Zahl (Ist ANSI, muß also vorkommen)
Ist aber auch nichts halbes und nichts ganzes.
Würde den komprimierten String in Memory halten,
senden und dann erst in eine Datei schreiben.
Das verhindert auch Synchronisationsprobleme und
ist schnell.
Die Komprimierung wird (hoffentlich) so selten auf-
gerufen, daß dies (was wir durchaus auch in Erwägung
gezogen hatten) im Schnitt über alle Zugriffe kaum
eine Beschleunigung bringen würde.
War mir jetzt nicht um Geschwindigkeit, sondern eher um Einfachheit ;-)
Komprimieren im Hauptspeicher war bei meiner ersten
Perl-Implementierung (unter Verwendung von /bin/gzip)
gar nicht möglich und ist es auf meiner Domain (wo
kein Compress::Zlib installiert ist) auch jetzt noch
nicht. Zudem würde es mehr Speicher kosten, ohne
dafür eine nennenswerte Beschleunigung zu bewirken ...
Compress::Zlib würde eine in-memory-Komprimierung
bieten, aber ich sehe im Moment wenig Sinn darin.
Es ist bedeutend simpler.
Ich sehe auch nicht, wie das Komprimieren im RAM
Synchronisationsprobleme verhindern würde.
Irgendwann muß das Ergebnis der Komprimierung in
die Cache-Datei geschrieben werden - und dazu ist
entweder eine explizite Synchronisation notwendig,
falls gleich in die endgültige Datei geschrieben
werden soll (und nachfolgende lesende Cache-Zugriffe
müssen damit ebenfalls umgehen können)
Ja gut, das Argument muß ich gelten lassen.
Ein Locking Mechanismus würden die Simplizität wieder ruinieren ;-)
oder eben
die Trivial-Methode, nur fertige Dateien durch Umbe-
nennung um Cache "sichtbar" für andere Zugriffe zu
machen.
Na, _so_ trivial ist sie ja auch nicht ,-)
Globale, ja selbst nur lokale eindeutige Dateinamen
zu finden ist schwierig. Da sollte eigentlich
tmpfile() bzw tmpname() für einspringen.
In unserem Falle reicht es, $PID an den späteren
Namen der Cache-Datei anzuhängen. Im Cache gibt es
nur Dateien, die auf ".gz" enden, und solche tempo-
räre Dateien, die über ihre Endung unique sind.
getpid() ist ja leider nicht in ANSI C.
Darum ging es ja im Grunde genommen.
so short
Christoph Zurnieden