Seite 1 von 3 1 2 3 LetzteLetzte
Ergebnis 1 bis 20 von 51

Thema: Zend_Cache Refactoring

  1. #1
    Benutzer Avatar von mabe
    Registriert seit
    09.06.2009
    Ort
    Berlin
    Beiträge
    52
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard Zend_Cache Refactoring

    Hi,

    ich habe eine komplett überarbeitete Zend_Cache Komponente in Ready for Review eingestellt. Das Ziel soll sein fehlende Funktionen in Zend_Cache zu integrieren (z.B. tagging für alle), bessere Performance zu erreichen (z.B: das file backend ist nach dem umschreiben bis zu 40% schneller - benchmaks kommen noch), und außerdem soll die Komponente einfacher benutzt werden können.

    Guckts euch einfach mal an, Rückmeldung auf Zend wäre echt nett
    http://framework.zend.com/wiki/displ...Marc+Bennewitz

    Greets

  2. #2
    Erfahrener Benutzer
    Registriert seit
    28.12.2006
    Beiträge
    9.966
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Ein weiter Zend-Contributor im Forum, herzlich Willkommen
    das file backend ist nach dem umschreiben bis zu 40% schneller
    Wie das? Oo

    Guckts euch einfach mal an, Rückmeldung auf Zend wäre echt nett
    Is bookmarked ^^

    ich habe eine komplett überarbeitete Zend_Cache Komponente in Ready for Review eingestellt.
    Machste dann gleich mit Zend_Log weiter? Bootstrapping mit grundsätzlich verschiedenen Konstruktor-Formaten macht kein Spass

  3. #3
    Super-Moderator Avatar von Kaiuwe
    Registriert seit
    30.12.2006
    Beiträge
    5.096
    Thanks
    2
    Thanked 321 Times in 252 Posts

    Standard

    Passend zum Thema 2.0: „Zend Framework Components - Developer Notes“.

  4. #4
    Benutzer Avatar von mabe
    Registriert seit
    09.06.2009
    Ort
    Berlin
    Beiträge
    52
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    @KingCrunch

    Das Hauptproblem des alten File Backends ist, dass die expire time in die cache dateien geschrieben wird und dadurch beim durchsuchen bzw. lesen/testen diese erst einmal ausgelesen werden muss.
    -> die neue Variante erstellt lediglich die cache datei mit dem aktuellen Zeitstempel. Beim Überprüfen kann die expire time dann berechnet werden, ohne die Datei öffnen zu müssen.

    Zudem wird beim schreben der Datien mit fopen & Co. gearbeitet, aber die neue Variante kommt mit file_put_contents aus.


    @Kaiuwe
    Deprecatet Warnungen und Rückwärtskompatiblität könnte denke ich implementiert werden, macht aber nur sinn, wenn das noch vor 2.0 in den Code soll. Wenn erst mit den Startschuss zu 2.0, dann müssen trotzdem noch en Paar kleinigkeiten angepasst werden (z.B: Zend_Cache_Backend_Interface umbenennen zu Zend_Cache_Backend_BackendInterface)

  5. #5
    Erfahrener Benutzer Avatar von robo47
    Registriert seit
    03.01.2007
    Ort
    Weiher im tiefsten Odenwald
    Beiträge
    176
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Wenn man sich nur auf die Zeitstempel des Dateisystems verlässt, kann es dann nicht zu Problemen kommen wenn das Dateisystem z.b. so gemountet ist dass beim lesen/ändern keine anpassungen stattfinden (hab irgendwie sowas noch im kopf wo es um APC ging und warum der unter umständen geänderte Dateien nicht erkennen kann wenn das dateisystem unter linux mit speziellen parametern gemountet ist um unnötige schreibzugriffe zu sparen)

    Bin mir da gerade nicht ganz sicher wie genau das war.

  6. #6
    Benutzer Avatar von mabe
    Registriert seit
    09.06.2009
    Ort
    Berlin
    Beiträge
    52
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Eigentlich mountet man das Dateisystem mit "noatime" um unnötige Schreibzugriffe zu vermeiden, dass hat aber nur Auswirkungen auf die "last access time".

    Ich bin der Meinung, dass wenn man einen File-Cache nutzt, das Fs auch die "last modification time" aktualisieren sollte / muss. Im übrigen fällt mir auch kein Fs ein, welches dieses Feature nicht standardmäßig nutzt.

    Wenn es umbedingt ohne funktionieren muss sollte die zu nutzende Variante über eine zusätzliche Funktion ausgewählt werden können.

  7. #7
    Moderator Avatar von Bleistift
    Registriert seit
    14.12.2006
    Ort
    Zürich (Schweiz)
    Beiträge
    1.580
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Man könnte ja nach dem Schreiben des Cache-Files prüfen, ob die "last modification time" korrekt gesetzt wurde und gegebenenfalls reagieren.
    Moderator
    Kein ZF-Support via Foren-PN

  8. #8
    Erfahrener Benutzer Avatar von ice-breaker
    Registriert seit
    29.03.2008
    Ort
    Steinbach/Taunus
    Beiträge
    1.862
    Thanks
    0
    Thanked 9 Times in 5 Posts

    Standard

    Zitat Zitat von mabe Beitrag anzeigen
    Das Ziel soll sein fehlende Funktionen in Zend_Cache zu integrieren (z.B. tagging für alle)
    mich würde interessieren wie du Tagging in Engines wie APC oder Memcached implementieren willst, die keine atomaren Operationen unterstützen?
    Nen, Eintrag anzulegen, dass man gerade die Tags modifiziert und deswegen niemand anders den Eintrag bearbeiten darf, kostet wieder mehr Zugriffe und erhöht wiederum das Locking-Verhalten, welches in Memcached dank Mutexen ja komplett eliminiert wurde.

    Ich hätte aber noch 1 Wunsch:
    1. eine loadMultiple()-Methode mit der ich aus einem Cache in einer Operation mehrere Ids holen kann (memcached kann das, spart IO-Operationen) und Backends die es nicht unterstützen simulieren es einfach durch mehrere load-Zugriffe.
    Das du die Memcached-Benennung an die PHP-Extension-Benennung angepasst hast, gefällt mir sehr gut.
    "Die Wahrheit entgeht dem, der nicht mit beiden Augen sieht." -Orici

  9. #9
    Benutzer Avatar von mabe
    Registriert seit
    09.06.2009
    Ort
    Berlin
    Beiträge
    52
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    @Bleistift
    Das wäre eine Möglichkeit, aber diese würden auch wieder zusätzliche Fs-Operationen mit sich bringen, zudem man extra ein touch aufrufen muss, da man nicht 100%ig die genau zeit beim schreiben weiß.

    @ice-breaker
    Wenn Tagging im Backend nicht implementiert ist, dann schreibe ich die eingehenden tags als Referenz ein eine extra cache id und ein zusätzliche Info in den cache selbst (Nur wenn beim Speichern Tags angegeben wurden)
    -> Beim clean/getIds kann man dann die Referenz der zu suchenden Tags durchlaufen
    -> Beim löschen werden die zu dem Cache gehörenden Referenzen auch mit entfernt

    Das ist natürlich lange nicht so performant und sicher, als wenn es direkt im Backend implementiert ist, aber soll ja hautsächlich die Funktionalität des Backends nacharmen.

    -> Ein Blick in mein svn (siehe proposal) in die Klasse Zend_Cache_Frontent_Core hilft dir sicher weiter.


    Was genau soll die Methode loadMultiple genau zurück geben?
    -> eine Liste von Ids -> siehe getIds
    -> eine Liste mit allen Ids und dessen Cache-Inhalt halte ich für nicht praktikabel

  10. #10
    Moderator Avatar von Bleistift
    Registriert seit
    14.12.2006
    Ort
    Zürich (Schweiz)
    Beiträge
    1.580
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Zitat Zitat von mabe Beitrag anzeigen
    @Bleistift
    Das wäre eine Möglichkeit, aber diese würden auch wieder zusätzliche Fs-Operationen mit sich bringen, zudem man extra ein touch aufrufen muss, da man nicht 100%ig die genau zeit beim schreiben weiß.
    Cache-Schreiben ist ja sowieso langsam und wird darum auch selten gemacht:
    Das Schreiben auf die Platte selber ist schon langsam und ausserdem müssen die Daten, die gecacht werden sollen, dann ja auch geladen werden (DB o.Ä.)

    Ich glaube viel Zeit ginge da nicht verloren. Müsste man halt testen.
    Moderator
    Kein ZF-Support via Foren-PN

  11. #11
    Benutzer Avatar von mabe
    Registriert seit
    09.06.2009
    Ort
    Berlin
    Beiträge
    52
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Ich glaube es wäre das beste die mtime-Funktionalität im Fs beim Konstruktor bzw. beim setzen von cache_dir zu überprüfen und trotzdem eine Option dafür bereit zu stellen.

    -> Wenn Funktionalität nicht verfühgbar ist, aber die Option aktiviert ist müsste natürlich eine Exception geworfen werden.

  12. #12
    Erfahrener Benutzer Avatar von robo47
    Registriert seit
    03.01.2007
    Ort
    Weiher im tiefsten Odenwald
    Beiträge
    176
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Zitat Zitat von mabe Beitrag anzeigen
    @ice-breaker
    Wenn Tagging im Backend nicht implementiert ist, dann schreibe ich die eingehenden tags als Referenz ein eine extra cache id und ein zusätzliche Info in den cache selbst (Nur wenn beim Speichern Tags angegeben wurden)
    -> Beim clean/getIds kann man dann die Referenz der zu suchenden Tags durchlaufen
    -> Beim löschen werden die zu dem Cache gehörenden Referenzen auch mit entfernt

    Das ist natürlich lange nicht so performant und sicher, als wenn es direkt im Backend implementiert ist, aber soll ja hautsächlich die Funktionalität des Backends nacharmen.
    Im Falle von limitierten Caches wie APC die irgendwann voll sind bedeutet das dann aber wenn der Cache voll ist und anfängt Elemente zu löschen, fliegen unter umständen die einträge raus die für die Verknüpfungen zuständig sind oder ? Jenachdem wie ich auf die Einträge zugreife hab ich so unter umständen dann Leichen die noch genutzt werden die ich aber nicht mehr finden kann.

    Ich würde mir da eher wünschen dass man bei Systemen die keine Tags unterstützen eine Art Adapter hat der diese Assoziation herstellt und man sich hier dann selbst entscheiden kann was man will, sei es dass man bereit ist das Risiko einzugehen und einen APC-Adapter nutzt, oder dass man die tags in einem anderen Medium speichert (dateisystem, sqlite/dbms, ... )

    Ich denke da an etwas in der Richtung: http://pollinimini.net/blog/tags-emulation-zendcache

  13. #13
    Moderator Avatar von Bleistift
    Registriert seit
    14.12.2006
    Ort
    Zürich (Schweiz)
    Beiträge
    1.580
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Zitat Zitat von robo47 Beitrag anzeigen
    Ich würde mir da eher wünschen dass man bei Systemen die keine Tags unterstützen eine Art Adapter hat der diese Assoziation herstellt und man sich hier dann selbst entscheiden kann was man will, sei es dass man bereit ist das Risiko einzugehen und einen APC-Adapter nutzt, oder dass man die tags in einem anderen Medium speichert (dateisystem, sqlite/dbms, ... )
    Man könnte ja dafür eine Option bieten... Standard ist der eigene Adapter. Man kann allerdings auch einen eigenen Adapter definieren.
    Also:
    PHP-Code:
    $backendOptions = array(
        
    'tag_handler' => Zend_Cache::factory('Core',
                                             
    'File',
                                             array(
    'lifetime' => 7200),
                                             array(
    'cache_dir' => './tmp/'))
    );
    $cache Zend_Cache::factory('Core',
                                 
    'APC',
                                 
    $frontendOptions,
                                 
    $backendOptions); 
    Moderator
    Kein ZF-Support via Foren-PN

  14. #14
    Erfahrener Benutzer
    Registriert seit
    28.12.2006
    Beiträge
    9.966
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Also bei sowas tendiere ich lieber zu eigenen Klassen, was die Wartung vereinfacht und den Konfigurationswahn etwas eindämmt

  15. #15
    Benutzer Avatar von mabe
    Registriert seit
    09.06.2009
    Ort
    Berlin
    Beiträge
    52
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Im Falle von limitierten Caches wie APC die irgendwann voll sind bedeutet das dann aber wenn der Cache voll ist und anfängt Elemente zu löschen, fliegen unter umständen die einträge raus die für die Verknüpfungen zuständig sind oder ? Jenachdem wie ich auf die Einträge zugreife hab ich so unter umständen dann Leichen die noch genutzt werden die ich aber nicht mehr finden kann.
    Ja Richtig das ist ein Problem, wobei die evtl. entstehenden Leichen aber durch clean all bzw. durch erreichen der Laufzeit automatisch gelöscht werden.

    Dafür einen Handler als Option anzubieten ist eine gute Idee. Ich würde sagen, dass ein definierter Tag-Handler das Zend_Cache_Backend_Interface implementieren muss (also ohne frontend arbeitet) und als Default-Wert das aktuelle Backend genutzt wird. Damit ist die zusätzliche Option optional und man kann die Tag-Implementierung auch auf einen eigenen Handler lenken, wenn das Backend tagging implementiert hat.

  16. #16
    Moderator Avatar von Bleistift
    Registriert seit
    14.12.2006
    Ort
    Zürich (Schweiz)
    Beiträge
    1.580
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Zitat Zitat von mabe Beitrag anzeigen
    Ich würde sagen, dass ein definierter Tag-Handler das Zend_Cache_Backend_Interface implementieren muss (also ohne frontend arbeitet) und als Default-Wert das aktuelle Backend genutzt wird. Damit ist die zusätzliche Option optional und man kann die Tag-Implementierung auch auf einen eigenen Handler lenken, wenn das Backend tagging implementiert hat.
    Ja, das finde ich eine gute Idee.
    Moderator
    Kein ZF-Support via Foren-PN

  17. #17
    Erfahrener Benutzer Avatar von robo47
    Registriert seit
    03.01.2007
    Ort
    Weiher im tiefsten Odenwald
    Beiträge
    176
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    Gefällt mir

  18. #18
    Erfahrener Benutzer Avatar von ice-breaker
    Registriert seit
    29.03.2008
    Ort
    Steinbach/Taunus
    Beiträge
    1.862
    Thanks
    0
    Thanked 9 Times in 5 Posts

    Standard

    Zitat Zitat von mabe Beitrag anzeigen
    Wenn Tagging im Backend nicht implementiert ist, dann schreibe ich die eingehenden tags als Referenz ein eine extra cache id und ein zusätzliche Info in den cache selbst (Nur wenn beim Speichern Tags angegeben wurden)
    -> Beim clean/getIds kann man dann die Referenz der zu suchenden Tags durchlaufen
    -> Beim löschen werden die zu dem Cache gehörenden Referenzen auch mit entfernt

    Das ist natürlich lange nicht so performant und sicher, als wenn es direkt im Backend implementiert ist, aber soll ja hautsächlich die Funktionalität des Backends nacharmen.

    -> Ein Blick in mein svn (siehe proposal) in die Klasse Zend_Cache_Frontent_Core hilft dir sicher weiter.
    hmm, ich persönlich finde es eben nicht besonders sinnvoll dem Entwickler Tags zu versprechen, wenn es im Prinzip nur ne "halbherzige" Implementierung ist, der Cache kann sie wegwerfen oder bei parallen Schreibzugriffen ist nicht garantiert was passiert (fehlendes Locking-> Race conditions).
    Also ich würde den Vorschlag, dass wenn ein Backend keine Tags unterstützt, es als extra Adapter zu implementieren deutlich besser finden.
    Sonst muss ich mich bei jedem Cache informieren gehen welche Sicherheit ich bekomme (leider werden das einige nicht machen).
    Mit extra Adaptern könnte man gleich angeben, welchen "Sicherheitsstandard" (Persistenz, Atomarität) dieser unterstützt, und diesen auch konfigurieren (Atomarität (de)aktivieren für Performance/Sicherheit)

    Zitat Zitat von mabe Beitrag anzeigen
    Was genau soll die Methode loadMultiple genau zurück geben?
    -> eine Liste von Ids -> siehe getIds
    -> eine Liste mit allen Ids und dessen Cache-Inhalt halte ich für nicht praktikabel
    genau das !
    Und es ist sehr praktikabel ich beschreibe gerade mal eine Anwendung:
    Eine Anwendung ist so groß gewachsen, das einige DB-Server schon nicht mehr reichen, die Daten müssen geshardet werden. Nun möchte das Model (Beispiel nimmt dieses Forum) welches gerade für den View die darzustellenden Informationen zusammensammelt, zu jedem Post (der eine User-Id hat) die Kurzinfo des Bernutzers laden (rechte Seite ).
    Nach deinem Verfahren sind es hier aktuell ca. 6 Zugriffe (also 6 mal einen anderen Server kontaktieren) auf den Cache (alle Benutzer, die etwas gepostet haben), hätten wir aber eine dicke Memcached-Maschine mit viel Ram, würde ein einzelner Aufruf reichen, wir hätten uns als 10 IO-Zugriffe (versimpelt 5 Senden, 5 Empfangen) gespart und zudem ordentlich Load von dem Cache genommen.
    Also so unsinnig ist das nicht, es wurde nicht ohne Grund in Memcached implementiert
    Geändert von ice-breaker (10.06.2009 um 17:18 Uhr)
    "Die Wahrheit entgeht dem, der nicht mit beiden Augen sieht." -Orici

  19. #19
    Benutzer Avatar von mabe
    Registriert seit
    09.06.2009
    Ort
    Berlin
    Beiträge
    52
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Standard

    hmm, ich persönlich finde es eben nicht besonders sinnvoll dem Entwickler Tags zu versprechen, wenn es im Prinzip nur ne "halbherzige" Implementierung ist, der Cache kann sie wegwerfen oder bei parallen Schreibzugriffen ist nicht garantiert was passiert (fehlendes Locking-> Race conditions).
    Also ich würde den Vorschlag, dass wenn ein Backend keine Tags unterstützt, es als extra Adapter zu implementieren deutlich besser finden.
    Sonst muss ich mich bei jedem Cache informieren gehen welche Sicherheit ich bekomme (leider werden das einige nicht machen).
    Mit extra Adaptern könnte man gleich angeben, welchen "Sicherheitsstandard" (Persistenz, Atomarität) dieser unterstützt, und diesen auch konfigurieren (Atomarität (de)aktivieren für Performance/Sicherheit)
    Ich hoffe, dass ist mit einer Instanz von Zend_Cache_Backend_Interface als Tag Handler (siehe oben) ok.

    Zitat:
    Zitat von mabe
    Was genau soll die Methode loadMultiple genau zurück geben?
    -> eine Liste von Ids -> siehe getIds
    -> eine Liste mit allen Ids und dessen Cache-Inhalt halte ich für nicht praktikabel


    genau das !
    Und es ist sehr praktikabel ich beschreibe gerade mal eine Anwendung:
    Eine Anwendung ist so groß gewachsen, das einige DB-Server schon nicht mehr reichen, die Daten müssen geshardet werden. Nun möchte das Model (Beispiel nimmt dieses Forum) welches gerade für den View die darzustellenden Informationen zusammensammelt, zu jedem Post (der eine User-Id hat) die Kurzinfo des Bernutzers laden (rechte Seite ).
    Nach deinem Verfahren sind es hier aktuell ca. 6 Zugriffe (also 6 mal einen anderen Server kontaktieren) auf den Cache (alle Benutzer, die etwas gepostet haben), hätten wir aber eine dicke Memcached-Maschine mit viel Ram, würde ein einzelner Aufruf reichen, wir hätten uns als 10 IO-Zugriffe (versimpelt 5 Senden, 5 Empfangen) gespart und zudem ordentlich Load von dem Cache genommen.
    Also so unsinnig ist das nicht, es wurde nicht ohne Grund in Memcached implementiert
    Was du meinst ist eine feste Liste (also keine Suche mittels MATCH_*), sondern etwas in der Art:
    lade den Inhalt folgender Cache-Ids id1, id2 ...

    -> Die Idee klingt ganz gut, finde ich aber besser, wenn man das direkt mit der load/test methode verknüpft:

    Ich würde allerdings sagen, dass bei load nur valide Inhalte zurückgegeben werden, wobei mittels test alle angefragten cache-ids zurück geliefert werden.

    {code}
    $cache->test(array('id1', 'id2', 'id3')); // return array('id1' => [mtime], 'id2' => false, 'id3' => [mtime])
    $cache->load(array('id1', 'id2', 'id3')); // return array('id1' => 'content1', 'id3' => 'content3')
    {code}

  20. #20
    Erfahrener Benutzer Avatar von ice-breaker
    Registriert seit
    29.03.2008
    Ort
    Steinbach/Taunus
    Beiträge
    1.862
    Thanks
    0
    Thanked 9 Times in 5 Posts

    Standard

    Zitat Zitat von mabe Beitrag anzeigen
    Was du meinst ist eine feste Liste (also keine Suche mittels MATCH_*), sondern etwas in der Art:
    lade den Inhalt folgender Cache-Ids id1, id2 ...
    jup, und das eben, falls das Backend es unterstützt in einer Operation, wie bei Memcache::get mit einem Array als Parameter

    Zitat Zitat von mabe Beitrag anzeigen
    -> Die Idee klingt ganz gut, finde ich aber besser, wenn man das direkt mit der load/test methode verknüpft:

    Ich würde allerdings sagen, dass bei load nur valide Inhalte zurückgegeben werden, wobei mittels test alle angefragten cache-ids zurück geliefert werden.

    {code}
    $cache->test(array('id1', 'id2', 'id3')); // return array('id1' => [mtime], 'id2' => false, 'id3' => [mtime])
    $cache->load(array('id1', 'id2', 'id3')); // return array('id1' => 'content1', 'id3' => 'content3')
    {code}
    ist auch ok, sofern es dann auch die nativen Funktionalitäten nutzt (und wenn nicht vorhanden die emulierten), sonst kann ich mir das gleich auch sparen.

    Da fällt mir was ein, bei einem File-Backend könnte man das doch mit Partitionierung verknüpfen oder?
    So dass die Ids "user_$username" caches bekommen wo mehrere Entrys in einem File liegen (und dann nur usernames und nicht noch andere), so dass man die Anzahl zu öffnender Dateien senken könnte.
    Also nen Array übergeben nach dem partioniert wird, für Keys die nicht darauf zutreffen, nutzt man die alte Methode.
    Könnte die Performance nochmal ordentlich steigern, wenn man viele Daten aus einem Cluster lädt statt aus jeweils einzelnen Files.
    "Die Wahrheit entgeht dem, der nicht mit beiden Augen sieht." -Orici

Seite 1 von 3 1 2 3 LetzteLetzte

Ähnliche Themen

  1. Zend_Cache
    Von marlinx im Forum Core
    Antworten: 12
    Letzter Beitrag: 29.03.2009, 23:18
  2. Zend_Cache
    Von Innocentus im Forum Einsteigerfragen
    Antworten: 5
    Letzter Beitrag: 28.01.2009, 18:19
  3. Zend_Cache Verbesserungen ?
    Von ice-breaker im Forum Core
    Antworten: 2
    Letzter Beitrag: 06.09.2008, 21:11
  4. Refactoring
    Von vincent-de im Forum Einsteigerfragen
    Antworten: 0
    Letzter Beitrag: 05.08.2007, 19:59
  5. Refactoring in PHP?
    Von jpieper im Forum PHP X-Talk
    Antworten: 0
    Letzter Beitrag: 19.04.2007, 20:28

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •