Seite 1 von 1

Daten im Speicher halten

Verfasst: Dienstag 25. November 2008, 17:27
von muli
Ich bin ein Neuling auf dem Gebiet, möchte aber eine Anwendung schreiben bei der ich einmalig Daten hochlade und diese dann am besten in einer Pythonklasse oder auch nur in einem Dict oder eingentlich egal speichere. Die Klasse soll dann am besten jedes mal wenn ich von meinem Browser aus ein Script aufrufe die Daten zur verfügung haben ohne sie aus einer Datei zu lesen.
D.h. die Instanz meiner Klasse soll im Speicher bleiben bis ich sie nicht mehr brauche.

Wie macht man so was am besten. Ist sowas überhaupt möglich?
Also ich vermute mal das ich dafür sowas wie FastCGI oder modpython verwenden muss da diese den Interpreter nicht jedesmal neu starten.
Kann ich dann einfach per FastCGI eine funktion aufrufen welche dann meine Klasse erstellt? und diese dann bei weiteren Skriptaufrufen nutzen? aber wann wird sie dann überhaupt genutzt?

Bin für jede Hilfe Dankbar die mir ein wenig die Richtung weisen kann.

Verfasst: Dienstag 25. November 2008, 18:11
von Jan.O
Ich wollte mal genau das selbe realisieren. Bin dann hinterhet bei CherryPy gelandet. CherryPy ist ein python application server. das heißt, er läuft dauerhaft als ein einzelnes "python-script", welches du erweiterst. Variablen die du dann anlegst, bleiben bestehen. Du kannst natürlich auch andere frameworks verwenden

http://www.cherrypy.org/

Jan

Verfasst: Dienstag 25. November 2008, 19:40
von Leonidas
Uh, es ist eigentlich üblich so Daten auf dem Server irgendwie zu speichern, ob jetzt im Speicher oder irgendwo ist eigentlich egal. FastCGI-Prozesse laufen in der Regel lange, aber man würde trotzdem nicht wollen, dass die Daten bei einem Restart einfach weg sind.

Verfasst: Dienstag 25. November 2008, 20:25
von muli
ok zunächst mal danke für die Antworten!
@Jan.O: Ich dachte es gäbe irgendwie eine leichtgewichtigere Sache. Das ganze soll auf einem Apache server laufen da ist es doch irgendwie zuviel noch diesen Cherrypy server draufzuhauen, oder? bin wie gesagt anfänger.

@leonidas: Ja daten speichern aber ich möchte die nicht auf irgendeiner Festplatte haben. Egal in welcher Form(weder datei noch DB oder sonnst was). Das wäre unnötig die Daten von der Platte in den Arbeitsspeicher zu laden und dann die veränderten wieder auf der Platte zu speichern.

Also ich habe mir das so vorgestellt :
Ich rufe meine Internet seite auf Lade Daten einfach mit einem Form hoch, erschaffe ein object im Arbeitsspeicher( so wie bei c++ mit new) . Dann Arbeite ich damit bis ich es wieder los werden will(oder ein Garbage collector entscheidet das man es nicht mehr braucht). Das Arbeiten habe ich mir so wie mit CGI vorgestellt das ich einfach skripte aufrufe die dann aber auf dieses Global angelegte Datenobjekt zugreifen können.
Und das halt ohne eine Datenankanfrage oder eine Datei zu laden!
Wenn ich dieSeite nochmal Aufrufe sollen die Daten weg sein und man soll die möglichkeit haben mit anderen Daten zu arbeiten.
Das alles halt so leichtgewichtig wie möglich!

Verfasst: Dienstag 25. November 2008, 22:31
von Leonidas
Darf man fragen, wou du das machen willst bzw was du dir davon versprichst?

Verfasst: Mittwoch 26. November 2008, 01:01
von BlackJack
@muli: Das klingt irgendwie nach Anforderungen von denen Du gar nicht weisst, ob Du sie brauchst. "Premature optimization". Du weisst, dass CherryPy nicht leichtgewichtig genug ist, sagst aber im gleichen Atemzug, dass Du gar nicht weisst wie schwergewichtig CherryPy ist.

Wenn Du Daten im Speicher behalten willst, muss sowieso ein Python-Interpeter ständig laufen. Ob er das nun als Teil vom Apachen macht, oder in Form von CherryPy ist doch eigentlich egal. Wobei man da den Apachen sogar weglassen kann, zum Beispiel beim Testen auf dem Entwicklungsrechner.

Verfasst: Mittwoch 26. November 2008, 09:09
von veers
Leonidas hat geschrieben:Uh, es ist eigentlich üblich so Daten auf dem Server irgendwie zu speichern, ob jetzt im Speicher oder irgendwo ist eigentlich egal. FastCGI-Prozesse laufen in der Regel lange, aber man würde trotzdem nicht wollen, dass die Daten bei einem Restart einfach weg sind.
...Oder wie viele Prozesse gestartet werden

Re: Daten im Speicher halten

Verfasst: Mittwoch 26. November 2008, 10:12
von Qubit
muli hat geschrieben: Bin für jede Hilfe Dankbar die mir ein wenig die Richtung weisen kann.
Was du suchst, ist wohl ein Cache, der threadsafe ist und ein API bietet ;-)
http://www.danga.com/memcached

Verfasst: Mittwoch 26. November 2008, 20:18
von muli
also Ich will folgendes damit machen.
Aus meinen Daten wurde ein Bayesches Netzt generiert! Nun möchte ich dieses Netz darstellen. Das mach ich mit sowas wie GraphViz oder so darunter werden die Daten Dargestellt dafür verwende ich Timepedia Chronoscope (das ist javascript kram und läuft clientseitig).
Die Daten sowie das Netz sind in Xml gegeben und sollen einfach hochgeladen werden, dann diese dargestellt werden und verschiedene Berechnungen angestellt werden.Jetzt möchte ich ja nicht jedesmal die Daten neu aus einer Dateiladen bzw zum server schicken. Deshalb dachte ich irgendwie die sachen auf dem Server Im Speicher zu halten.
Ich habe da ein wenig mit zope herumprobiert und diese ZODB dazu verwendet die Daten zu speichern.
Das klappt auch nicht schlecht aber dieses ganze zopezeug ist mir dann doch zu viel drumherum.
Python möchte ich verwenden weil die ein paar hübsche und schnelle mathe sachen haben und mein code noch nie so ordentlich aussah. Dieses erzwungene einrücken hat schon so seine vorteile ;-)
@BlackJack: Das ich keinen Plan von diesem Kram habe habe ich doch schon gesagt darauf braucht man ja jetzt nicht noch weiter rumhacken!
Für mich klang das halt einfach so gedoppelt was ich da gelesen habe. Das der kram auf einem Apache läuft steht fest daran kann ich nichts ändern. und da dachte ich wenn cherrypy auch ohne Apache läuft... dann ist da doch irgenwas redundant.
@veers: Äh was willst Du mir damit sagen?Das unterumständen zu viele Prozesse gestartet werden?
@Qubit: Hmmm Ich weiss nicht so!
The Python client we'd previously released was just a prototype, and we don't have regular Python programmers on hand.
Das gefällt mir ja schon mal nicht so gut!
Ist denn das wirklich so kompliziert?
Ich will doch eigentlich nur selbst bestimmen wann der Interpreter neu gestartet wird oder?
Naja nicht ganz! Aufrufe von verschiedenen Personen sollen natürllich auch verschiedene Interpreter laufen haben.

:cry:

Verfasst: Mittwoch 26. November 2008, 20:57
von BlackJack
@muli: ZODB kann man auch unabhängig von Zope verwenden.

Verfasst: Donnerstag 27. November 2008, 04:56
von muli
Ich weiss aber ich will ja auch eigentlich keine Datenbank! Ob jetzt objektorientiert oder nicht.
Das ist ja immer mit DB anfragen verbunden ich dachte das wäre überflüssig wenn man die Daten doch einfach in den Speicher laden könnte. Das scheint aber offensichtlich nicht möglich zu sein.
ODER?

Puh ich merke an meinem Ton das ich langsam echt frustriert bin. Ich steh ein wenig unter Zeitdruck und dachte nicht das sowas so eine aussergewöhnliche Sache sei.
Ich danke euch jedenfalls allen schon mal für eure Mühen. :shock: :shock:

Verfasst: Donnerstag 27. November 2008, 08:08
von audax

Code: Alles auswählen

from time import sleep

a = 1
sleep(1)
print a
Ich hab die Daten im Speicher gehalten! \o/

Im Erst: Wenns Threadsafe und persistent sein soll: Nimm die ZODB.

Verfasst: Donnerstag 27. November 2008, 08:20
von Leonidas
muli hat geschrieben:@veers: Äh was willst Du mir damit sagen?Das unterumständen zu viele Prozesse gestartet werden?
Bei FastCGI werden unterschiedlich viele Prozesse gestartet, und es ist soweit ich weiß nicht sichergestellt, dass der Prozesse der den letzten Request abgearbeitet hat auch der gleiche Prozess ist wie der der den nächsten abarbeitet. Also kannst du die Daten in einem Prozess im Speicher halten, nur wird es dir nicht helfen, wenn der Request von einem anderen Prozess abgearbeitet wird. Da bräuchte man wohl etwas wie einen Tuple-Space, aber um ehrlich zu sein ist es wohl kaum den Aufwand wert, wenn man genausogut auch eine DB nutzen kann.

Verfasst: Donnerstag 27. November 2008, 09:24
von gerold
muli hat geschrieben:Ich steh ein wenig unter Zeitdruck
Hallo muli!

So wie ich das sehe, unterschätzt du die Geschwindigkeit des Apachen und des darunter befindlichen Linux-/Windows-Systems. Wenn du deine Daten in eine Datei schreibst und mit einer Lock-Datei den gleichzeitigen Schreibzugriff unterbindest, dann bist du nicht merkbar langsamer als wenn du alles selbst im Speicher hälst. Warum? Weil die Betriebssysteme nicht blöd sind. Wird eine Datei 100 mal die Sekunde angefordert, dann bleibt die im Cache und wird nicht jedes Mal neu eingelesen. Rein theoretisch könntest du sogar den Apachen ohne Zusatzsoftware für so etwas verwenden. Du installierst dir **mod_dav** und kannst damit direkt über HTTP Dateien auf dem Server verändern. Diese werden dann natürlich vom Apachen ausgeliefert.

Wenn du es komplizierter haben möchtest, und die Daten unbedingt im Speicher liegen müssen, dann brauchst du einen eigenständig laufenden Prozess, der nicht vom Apachen abgewürgt wird. Du kennst ja schon Zope. Zope kann als eigenständiger Prozess laufen. Zope bindet man gerne in den Apachen ein, indem man die Requests mit **mod_proxy** an den Zope-Prozess weiterleitet. Dieser arbeitet den Request ab und gibt den Response wieder an den Apachen zurück, damit dieser ihn an den Browser zurücksenden kann.

Genau so wie du es mit Zope machen kannst, kannst du auch ein CherryPy als eigenständig laufenden Prozess im Hintergrund laufen lassen. Du hast mehrere Möglichkeiten. CherryPy läuft in diesem Fall als eigengständiger Server. Du kannst CherryPy z.B. auf dem Port 8080 horchen lassen. Jede Anfrage eines Browsers, die an diesen Port gesendet wird, wird von CherryPy direkt beantwortet. Der Apache hat nichts damit zu tun. So bekommst du die beste Geschwindigkeit.

Du kannst CherryPy aber auch über **mod_proxy** in den Apachen einbinden. Wie mit Zope. Nur mit dem Unterschied, dass CherryPy sehr leichtgewichtig ist. Das hat den Vorteil, dass die Requests vom Apachen beantwortet werden. So kann der Apache auf Port 80 horchen, die Anfragen an CherryPy weitergeben und dann auch wieder beantworten.

Ich habe dir mit diesen Vorschlägen geantwortet, weil du geschrieben hast, dass du unter Zeitdruck bist. Und wenn du dich schon nicht davon überzeugen lässt, dass es unnötig ist, die Daten im Speicher zu halten, dann musst du in die bittere Pille beißen und die Daten im Speicher halten.

Unter Linux musst du dir zuerst ein aktuelles CherryPy installieren --> http://halvar.at/python/cherrypy_fastcg ... stallieren

Dann legst du dir am besten einen "Virtuellen Host" an in dem du arbeiten kannst --> http://halvar.at/python/cherrypy_fastcg ... llen-hosts

Dann musst du den CherryPy-Server beim Linuxstart starten lassen. Das machst du über einen Eintrag in */etc/init.d/* oder einem ähnlichen System. Hier die Datei */etc/init.d/cherrypy-halvar*, mit der ich auf einem Debian-Server den CherryPy-Prozess für http://halvar.at starte:
http://paste.pocoo.org/show/92753/

Das hier ist die Datei *001_halvar.conf*, mit der ich die Verbindung zwischen dem Apachen und CherryPy herstelle:
http://paste.pocoo.org/show/92755/

Für dich sind hauptsächlich die zwei Zeilen ab Zeile 53 wichtig. Damit wird CherryPy in den Apachen eingebunden.

Jetzt kann CherryPy alle Anfragen des Apachen beantworten und direkt aus dem Speicher holen.

mfg
Gerold
:-)

PS: Das hätte ich fast vergessen... So ein Universaldatenspeicher (für GET, POST und DELETE) für Textdaten könnte mit CherryPy so aussehen:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import cherrypy


datenspeicher = {}


class RestService(object):
    
    exposed = True
    
    def GET(self, key, *args, **kwargs):
        value = datenspeicher.get(key, None)
        if value:
            cherrypy.response.headers["Content-Type"] = "text/plain"
            return value
        else:
            raise cherrypy.NotFound
    
    def POST(self, key, value, *args, **kwargs):
        datenspeicher[key] = value
    
    def DELETE(self, key, *args, **kwargs):
        del datenspeicher[key]


def main():
    conf = {"/": {"request.dispatch": cherrypy.dispatch.MethodDispatcher()}}
    cherrypy.quickstart(RestService(), config = conf)


if __name__ == "__main__":
    main()
PS2: Und so sieht es aus, wenn dir die HTTP-Methoden egal sind:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import cherrypy


datenspeicher = {}


class Root(object):
    
    def get_value(self, key, *args, **kwargs):
        value = datenspeicher.get(key, None)
        if value:
            cherrypy.response.headers["Content-Type"] = "text/plain"
            return value
        else:
            raise cherrypy.NotFound
    get_value.exposed = True
    
    def set_value(self, key, value, *args, **kwargs):
        datenspeicher[key] = value
    set_value.exposed = True
    
    def delete_value(self, key, *args, **kwargs):
        del datenspeicher[key]
    delete_value.exposed = True


def main():
    cherrypy.quickstart(Root())


if __name__ == "__main__":
    main()
.

Verfasst: Donnerstag 27. November 2008, 18:07
von muli
Danke an alle!
Ihr seid echt klasse!

Ich denke ich werde dann mal cherrypy starten oder auch mit Zope weitermachen. Ich habe jedenfalls viel gelernt und bin euch echt dankbar.
Wenn die Zeit gekommen ist werde ich mich hoffentlich mal revanchieren können.

Danke muli :D