Philipp Hasenfratz: Session-Management und applikationsweit verfügbare Objekte

Beitrag lesen

Halihallo Eisbär

Diese Struktur lässt sich dann "ziemlich" einfach einlesen und bearbeiten => dies ist eine mögliche Serialisierung des Objektes.

Tatsächlich umfasst meine Applikation auch eine XML-Importschnittstelle, um komplexe Objekte von einem Fremdsystem zu übernehmen.
Nur habe ich grosse Bedenken, wenn ich mir die Module XML-Parser und -DOM anschaue, dass die Lösung bei mehreren dutzend bis hunderten Concurrent-Usern wirklich performant ist. Bei jedem Skriptaufruf der Darstellungsschicht werden mehrere Dutzend Objekte aus rund 10 Objektklassen aufgerufen. Falls ich diese jedesmal durch den XML-Parser duchjagen muss, belaste ich die Performance des Gesamtsystems beträchtlich (Zumindest glaube ich das, wobei Glauben ist nicht Wissen).

Dies hatte ich bei meinem zweiten Postings fälschlicherweise geschrieben, ja. Aber es gibt die Möglichkeit, die XML-Config _einmal_ zu parsen und den ParseTree von XML::DOM im Speicher zu halten. Dann kannst du über das Socket durch diesen ParseTree "browsen", aber es werden gar keine XML-Files mehr geparsed. Übrigens: XML::DOM ist auch ziemlich lahm. XML::SAX wäre da viel, viel schneller, aber das "browsing" wird etwas mühsamer, wie ich denke. Aber wie gesagt, die Datei muss nur einmal geparsed werden (OK, das Traversieren/Durchlaufen des ParseTree ist bei XML::DOM auch etwas unperformant).

Ganz allgemein zielt mein Posting darauf ab, diese persistente Datenspeicherung zwar zu haben, die daraus abgeleiteten Objekte aber zur Laufzeit "global" im Arbeitsspeicher verfügbar zu haben, um bei vielen gleichzeitigen Zugriffen die Performance zu verbessern.

s. oben.

Die Anforderung nach Stabilität steht bei meiner Lösung auch vor der Forderung nach Performance.

IMO ist das auch sehr sinnvoll ;-)

Von der Umsetzung her denke ich jedoch, dass ich bei jedem Skriptaufruf der Darstellungsschicht die Existenz des übergelagerten Prozesses prüfen kann und falls dieser nicht antwortet, wird er neu initalisiert (da die Daten trotz allem persistent gespeichert werden). In diesen (hoffentlich selteren) Fällen wartet der User halt 1-2 Sekunden länger.

Genau.

Nochmals ein Sorry, was bedeuted fork genau?

Brauchst dich net zu entschuldigen. Ich schreibe oft "komprimiert", wenn dann jemand etwas nicht versteht soll er nachfragen. Aber es bringt nix, wenn ich hier gleich eine ganze Doku zu fork verfasst hätte, schliesslich könntest du das ja schon wissen => deshalb frag nur immer nach.
Also, fork startet einen neuen Prozess => also eine neue Instanz des Programmes.

Wird dabei ein Prozess mitsammt seinem Speicher "geklont"?

Genau, sogar alle Filehandles... Es ist ein "perfektes" Abbild seines Vaters.

Und noch viel schlimmer, würde das unter WinNT/Win2000 auch funktionieren?

Ei, da muss ich dich enttäuschen. Bei der StandardDistribution von ActivePerl wird fork nicht unterstützt (vielleicht gibt's ne andere Lösung, denke aber nicht). Aber für Win gibt's Alternativen Win32::Process, Win32, jedoch wird dort der "Vater" nicht geklont, sondern du kannst lediglich ein neues Programm starten => XML müsste neu geparsed werden => wohl nicht so geeignet für dein Vorhaben.

(Eine der Kernanforderungen meiner Lösung ist, dass sie sowohl unter Linux, WinNT/Win2000 und FreeBSD laufähig sein muss).

Nun, fork läuft auf allen Unix-Derivaten. Bekanntlich gehört Win leider nicht dazu... *sorry*

Hm. Bin glaub ich etwas über das Ziel hinausgeschossen. SOAP und RPC sind IHO etwas langsam, da du ja eben genau die Performance damit verbessern willst. Zudem ist die Verwendung von SOAP und RPC eigentlich auch anders.
Du könntest dir natürlich Serialisierungsmöglichkeiten den Modulen entnehmen (zum Serialisieren wäre auch ein Blick in den Source von Data::Dumper nicht schlecht). Aber diese Module sind nich für TimeResistant-Programme gedacht, sondern eben dafür, dass die Objekt-Struktur auf über mehrere Scriptzugriffe hinaus gleich bleibt. Fakt ist, dass selber geschriebene SOAP-Module dennoch bei jedem Zugriff die Daten einlesen müssten => sprich, die Daten werden nicht im Speicher aufgewahrt, sondern auf der langsamen Platte.

Grundsätzlich könnte ich mir für diese Applikation durchaus ein SOAP-Interface vorstellen, da dies eh später als weitere Schnittstelle für externe Systeme angedacht ist. Zum Datenaustauch von Objekten innerhalb der Applikation möchte ich aber davon Abstand nehmen.

Stimmt. Also für externe Systeme kann ich SOAP nur empfehlen ;-))
Mir ist jedoch klar, dass es für den internen Gebrauch nicht einmal eine "Verschlimmbesserung" ist ;)

Direkt nein. Indirekt über die genannte Serialisierung. SOAP und RPC verwenden z. B. Serializer. Du könntest auch ein eigenes Modul schreiben, was eine Datenstruktur in einen XML-Stream abbildet.

Soweit ich das verstehe, ist SOAP und RPC vergleichbar zu dem, was wir uns oben zusammengedacht haben: Serialisierung der Objekte und Datenaustausch über eine Socketverbindung. Der einzige Unterschied ist, das dies standardisiert erfolgt.

Nun, das Serialisieren von Objekten ist nur ein "notwendiges Übel", es geht darum eine plattformunabhängige, systemübergreifende Schnittstelle zu realisieren, um Methoden, Prozeduren und Funktionen auf einem entfernten Rechner zu starten. Übrigens kann man wohl SOAP für Socketverbindungen benutzen, aber das "Standard-Transport-Medium" ist HTTP.

Somit verringert es mein Performanceproblem eher nicht.

Ja.

[...]

So was in der Art könnte ich mir vorstellen. Für die oben genannte XML-Schnittstelle habe ich mir schon ein XPath-ähnliches Interface geschrieben, werde nun aber auf das Modul XPath wechseln. Damit sollte sich so was grundsätzlich lösen lassen, aber wie gesagt, dazu muss jedes einzelne Objekt bei jedem Skriptaufruf nochmals durch den XML-Parser ... :-(

Mit einigen Anpassungen nicht. Der ParseTree liegt ja im Speicher des Daten-Scripts. Du musst dein XPath-Modul nur so abändern, dass es durch das Socket kommuniziert und ein anderes XPath-Modul im Daten-Script aufruft, der den Node zurückliefert (ohne das XML neu zu parsen => das XPath Modul muss auf den Memory-ParseTree von XML::DOM zugreifen).

Also irgendwie scheint mir das alles etwas zu Zeitaufwändig zu sein, nur um die Performance etwas zu verbessern. Müssten denn deine 50 Programme soviele Daten aus einer DB einlesen? - Könnte man das nicht etwas beschränken (z. B. nur Daten laden, wenn sie benötigt werden)? - Zudem glaube ich schon, dass die Performance einer reinen DB-Lösung nicht so schlecht wäre...

Danke für Deine reflektierenden Antworten, ich werde wohl eher bei der persistenten Datenspeicherung in einer Datenbank bleiben und die Objekte bei jedem Skriptaufruf neu aus der Datenbank generieren. Tatsächlich kann ich die Objektklassen so ausgestalten, dass der DB-Zugriff nur auf konkrete Anforderung erfolgt.

Es ist übrigens nicht schwer, ganze Objekte in der Datenbank abzubilden. Dazu brauchst du nur einen Mapper, der das Objekt in eine relationale Form bringt... Oder vielleicht hast du ja gar eine OODBMS ;)
Hab ich auch schon gemacht und funktioniert prima.

Dies wird zumindest vorläufig ausreichen. Später könnten aber Anforderungen folgen, wo ich enteder einen fetten Server hinstellen muss oder das Ganze gescheit in einer Applicationserver-Umgebung (WebObject, ASP oder andere) neu programmiere.

Musst dir jedoch im klaren sein, dass z. B. der IIS (eg. für ASP) die Objekte auch nicht immer im Speicher lässt!

Danke nochmals für Dein konstruktives Feedback und gute Nacht ;-)

bitte und guten Morgen ;-)

Viele Grüsse

Philipp