2009-09-17 10 views
8

Ich habe eine Server-Anwendung in Erlang gemacht. Darin habe ich eine Minnesattabelle , die einige Informationen auf Fotos speichern. Im Sinne von „alles ist ein Prozess“ Ich beschloss, in einem gen_server Modul die Tabelle zu wickeln, so dass das gen_server Modul die einzige ist, die direkt auf die Tabelle zugreift. Das Abfragen von und das Hinzufügen von Informationen zu dieser Tabelle erfolgt durch Senden von Nachrichten an diesen Prozess (der einen registrierten Namen hat). Die Idee ist, dass es mehrere Client Prozesse geben wird, die Informationen von dieser Tabelle abfragen.Verwenden von gen_server zum Kapseln einer Mnesiatabelle?

Das funktioniert ganz gut, aber das gen_server Modul hat keinen Zustand. Alles, was es erfordert, ist in der MNS-Tabelle gespeichert. Also, ich frage mich, ob ein gen_server ist vielleicht nicht das beste Modell für die Kapselung dieser Tabelle?

Sollte ich es einfach nicht zu einem Prozess machen, und stattdessen nur die Tabelle durch die Funktionen in diesem Modul kapseln? Im Falle eines Fehlers in diesem Modul würde das den aufrufenden Prozess zum Absturz bringen, was ich denke, könnte besser sein, weil es nur einen einzelnen Client betrifft, im Gegensatz zu jetzt, wenn es den gen_server Prozess verursachen würde abstürzen und alle ohne Zugriff auf die Tabelle verlassen (bis der Supervisor es neu startet).

Jede Eingabe wird sehr geschätzt.

Antwort

9

Ich denke, nach Occam's razor es besteht keine Notwendigkeit für diese gen_server- zu bestehen, zumal es absolut darin gespeichert kein Zustand ist. Ein solcher Prozess könnte in Situationen erforderlich sein, in denen Sie Zugriff auf die Tabelle (oder eine andere Ressource) haben müssen strikt sequenziell (zum Beispiel Sie möglicherweise möchten alle abgebrochenen Transaktionen auf Kosten eines Engpasses vermeiden).

Encapsulating Zugriff auf die Tabelle in einem Modul ist eine gute Lösung. Es erzeugt keine zusätzliche Komplexität, während ordnungsgemäße Ebene der Abstraktion und Kapselung.

6

Ich bin mir nicht sicher, ich verstehe, warum Sie beschlossen haben, eine Tabelle mit einem Prozess zu kapseln. Mnesia wurde entwickelt, um mehrere gleichzeitige Zugriffe auf Tabellen sowohl lokal als auch verteilt über einen Cluster zu vermitteln.

eine API-Modul erstellen, die alle bestimmten Tabellenzugriffsoperationen und Updates durchführt, ist eine gute Idee, wie die API-Funktionen, um Ihre Absicht besser im Code vermitteln wird, die sie nennt. Es wird lesbarer sein, als die Mnesien-Operationen direkt in den aufrufenden Code zu setzen.

Ein API-Modul gibt Ihnen auch die Möglichkeit, von Mnesia zu einem anderen Speichersystem zu wechseln später, wenn Sie benötigen. Die Verwendung von Mnesia-Transaktionen in Ihrem API-Modul schützt Sie vor einigen Programmierfehlern, da Mnesien Rollback-Vorgänge, die abstürzen, rückgängig macht. Das API-Modul ist immer für Anrufer verfügbar und ermöglicht es einer beliebigen Anzahl von Anrufern, Operationen gleichzeitig auszuführen, während eine gen_server-basierte API einen Fehlerpunkt hat, den Prozess, der die API nicht verfügbar machen kann.

Das einzige, was eine gen_server-basierte API über eine rein funktionale API bietet, ist die Serialisierung des Zugriffs auf die Tabelle - was eine ungewöhnliche Anforderung darstellt. Wenn Sie sie nicht unbedingt benötigen, wird sie zu einem Performance-Killer.

0

Es kann eine gute Idee sein, eine MNS-Tabelle mit einem einzigen gen_server-Prozess zu verarbeiten, wenn Sie schmutzigen Zugriff verwenden und Transaktionen vermeiden möchten. Dieser Ansatz ist möglicherweise schneller als txs, aber wie gewöhnlich müssen Sie ihn benchmarken.

Verwandte Themen