Ich habe ein Go-Projekt Ich möchte die Quelle öffnen, aber es gibt bestimmte Elemente, die nicht für OSS geeignet sind, z. firmenspezifische Logik etc.
Ich habe mir folgenden Ansatz ausgedacht:
interface
s sind im Core-Repository definiert. type
s das im Core definierte interface
s implementiert. Dadurch können die Plugins in komplett separaten Modulen untergebracht werden und haben somit eigene CI-Jobs etc. Dies würde zu einer Verzeichnisstruktur wie folgt führen:
%Vor%Mit einem Beispielworkflow von:
%Vor% Das einzige Problem, über das ich mir nicht sicher bin, ist, wie man die in Plugins definierten Typen zur Laufzeit in core zur Verfügung stellt. Ich würde reflect
lieber nicht verwenden, aber mir fällt im Moment kein besserer Weg ein. Wenn ich den Code in einem Repo machen würde, würde ich etwas wie:
Zusätzlich zu der obigen Frage würde dieser Gesamtansatz als idiomatisch betrachtet werden?
Dies ist eines meiner Lieblingsthemen in Go. Ich habe ein Open-Source-Projekt, das sich auch damit befassen muss ( Ссылка ), es hat eine Pluggable-DB und Runtime (Docker, k8s , Mesos, usw.) Clients. Vor dem Plugin-Paket, das sich im Haupt-Zweig von Go befindet (also sollte es bald zu einem stabilen Release kommen), habe ich gerade alle Plugins in die binäre und erlaubte Konfiguration kompiliert, welche zu verwenden ist.
Ab dem Plugin-Paket Ссылка können Sie die dynamische Verknüpfung für Plugins verwenden, ähnlich wie in Cs dlopen()
in seinem Laden, und das Verhalten von go's Plugin-Paket ist ziemlich gut in der Dokumentation beschrieben.
Zusätzlich empfehle ich, einen Blick darauf zu werfen, wie Hashicorp dies anwendet, indem er RPC über einen lokalen Unix-Socket ausführt. Ссылка
Der zusätzliche Vorteil, ein Plugin als separaten Prozess auszuführen, wie das Hashicorp-Modell, besteht darin, dass Sie eine große Stabilität erhalten, falls das Plugin versagt, aber der Hauptprozess diesen Fehler verarbeiten kann.
Ich sollte auch erwähnen, dass Docker seine Plugins in Go ähnlich verwendet, außer dass Docker HTTP statt RPC verwendet. Darüber hinaus hat ein Docker-Techniker über die Einbettung eines Javascript-Interpreters für dynamische Logik in der Vergangenheit Ссылка geschrieben.
Das Problem, auf das ich mit dem Muster des sql-Pakets hinweisen wollte, das in den Kommentaren erwähnt wurde, ist, dass es keine Plug-in-Architektur ist. Sie sind immer noch auf das beschränkt, was Sie importiert haben aber das ist kein Plugin, der Punkt eines Plugins ist so, dass das gleiche Programm entweder einen Code oder einen anderen Code ausführen kann. Was Sie mit Dingen wie dem SQL-Paket haben, ist Flexibilität, wo ein separates Paket bestimmt, welchen DB-Treiber zu verwenden. Nichtsdestoweniger ändern Sie den Code, um den von Ihnen verwendeten Treiber zu ändern.
Ich möchte hinzufügen, dass bei all diesen Plugin-Mustern, abgesehen von der Kompilierung in die gleiche Binärdatei und der Verwendung der Konfiguration, jede ihre eigene Build, Test und Deployment (dh ihre eigenen) haben kann CI / CD) aber nicht unbedingt.
Tags und Links go