Wie können Plugin-Systeme so gestaltet werden, dass sie nicht so viele Ressourcen verschwenden?

8

Ich versuche, ein einfaches Plugin-System zu erstellen, wie man es oft in einem CMS wie WordPress findet. Sie haben einen Ordner mit Plugins, die über Ereignisbenachrichtigungen mit einem Observer oder Event Designmuster mit dem Hauptsystem verknüpft sind.

Das Problem ist unmöglich damit das System weiß, auf welche Ereignisse das Plugin reagieren will - also muss das System jedes Plugin für jede Seitenanfrage laden finde heraus, ob dieses Plugin irgendwann benötigt wird. Unnötig zu sagen, dass genau dort eine Menge Ressourcen verschwendet werden - im Fall von WordPress, die sich für jede Anfrage um einige zusätzliche MB Speicher ergibt!

Gibt es alternative Möglichkeiten, dies zu tun?

Gibt es zum Beispiel eine Möglichkeit, all dies einmal zu laden und dann die Ergebnisse zwischenzuspeichern, damit Ihr System weiß, wie man Plugins lädt? Mit anderen Worten, das System lädt eine Konfigurationsdatei, die alle Ereignisse angibt, an die sich das Plugin binden will, und speichert es dann in APC oder etwas für zukünftige Anfragen?

Wenn das auch schlecht funktioniert, dann gibt es vielleicht eine spezielle Dateistruktur, die verwendet werden könnte, um fundierte Annahmen darüber zu machen, wann bestimmte Plugins nicht benötigt werden, um die Anfrage zu erfüllen.

    
Xeoncross 21.01.2012, 16:52
quelle

3 Antworten

3

Ich habe ein Plugin-Management-Tool, aber ich habe es nur mit überwiegend prozeduralen Plugins benutzt, und mit allen Includes normalerweise sofort geladen. Aber für eine ereignisbasierte und lazy-loading-API könnte ich mir vorstellen, flache Wrapper für die Plugin-Verwaltung zu verwenden und auf das automatische Laden für die tatsächlichen Erweiterungen zurückzugreifen.

%Vor%

In diesem Beispiel würde ich annehmen, dass die Plugin-API eine einfache Liste ist. Dieses Beispiel feature-plugin-123.php -Skript würde nichts tun, außer einem Array hinzuzufügen, wenn es geladen wird. Selbst wenn Sie ein Dutzend Feature-Plugins haben, würde dies nur einen zusätzlichen include_once bedeuten.

Aber die Hauptanwendung / oder Plugin-API könnte stattdessen die erwähnten Klassen instantiieren (entweder new $eventcb; für die rohen Klassennamen oder call_user_func_array für die Callbacks). Wobei wiederum die eigentliche Aufgabe auf einen Autoloader übertragen würde. Sie haben also ein duales System, bei dem ein Teil die Liste verwaltet, der andere den realen Code.

Ich stelle mir immer noch ein einfaches config.php vor, das nur Plugins und Einstellungen wie folgt auflistet:

%Vor%

Noch einmal im Hinterkopf, dass dies nur Wrapper / Datenskripte sind, mit der Plugin-Beschreibung für Managability. Man könnte auch eine tatsächliche register_even() API verwenden und in jeder eine zusätzliche Wrapper-Funktion definieren. Aber das Auflisten von Klassennamen scheint die einfachste Option zu sein.

Das oben erwähnte Management-Tool ist irgendwie rostig und hässlich: Ссылка Aber es ist nicht erforderlich, wenn Sie nur eine Liste (SQL-Tabelle) und keine Einstellungsverwaltung benötigen. Dieser Overhead dient nur dazu, die Metadaten des Plugins zu drucken und eine lesbare config.php zu behalten.

Fazit:

spl_autoload() auf dem include_path und eine einfache event- & gt; classname Registry, jeweils ein Wrapper Script, einfach alle auf einmal enthalten.

    
mario 22.01.2012, 02:23
quelle
2

Wordpress und andere CMS-Systeme sind sehr schlechte Beispiele.

Was wir verstehen müssen, ist, dass modular, fast immer schwerer ist.

Das beste Schema, mit dem ich jemals gearbeitet habe, um diese Situation zu lösen, ist ein klassenbasiertes Plugin mit einer strengen Namenskonvention, die einen automatischen Loader verwendet.

Bevor Sie das Plugin verwenden, müssen Sie also eine Instanz erstellen oder statische Funktionen verwenden.

Sie können das Plugin sogar wie folgt aufrufen:

%Vor%

zB:

%Vor%

Betreffend Ereignisse:

Sie müssen diese Ereignisse statisch registrieren, um zu vermeiden, dass sie dynamisch werden.

Die Datenbank wäre der richtige Ort dafür. Sie können eine Ereignistabelle und install () - und uninstall () -Methoden für die Plugin-Klasse verwenden, um bestimmte Ereignisse hinzuzufügen oder Methoden an andere Ereignisse zu binden. Es ist eine Datenbankabfrage, und wenn Sie mehr davon wollen, fügen Sie es zu Memcached oder zu einer flachen Ini-Datei hinzu.

Funktioniert gut für mich. Auf diese Weise war ich in der Lage, ein schweres System zu erhalten, das 8 MB pro Anfrage verbrauchte, um auf 1 MB herunterzufallen, mit genau der gleichen Liste von Funktionen, ohne fortgeschrittenes Caching. Jetzt können wir weitere Funktionen hinzufügen und das System "sauber" halten

Ich hoffe, das hilft

    
Guilherme Viebig 24.01.2012 14:19
quelle
0

Ich würde den Klassennamen des Plugins zusammen mit seinen abonnierten Ereignissen in einer Konfigurationsdatei speichern und dann die analysierte Konfigurationsdatei in APC speichern. Wenn ein Ereignis ausgelöst wird, kann das System die entsprechenden Plug-in-Klassen nach Bedarf laden.

    
Adam Pointer 21.01.2012 16:59
quelle