Ich gehe derzeit durch Elixier in Aktion und ich mache einige Refactoring meiner Todo
Anwendung Code, um einen besseren Einblick in die wichtigsten Teile von OTP.Ist es in Ordnung, Logik in einem Supervisor zu haben?
Die Anwendung verwendet eine Datenbank, die einfach Daten in Dateien auf der Festplatte speichert. Um sicherzustellen, dass der Zielordner für die Datenbank existiert, wird File.mkdir_p!(db_folder)
innerhalb des Datenbankprozesses aufgerufen. Der Datenbankprozess selbst verwendet eine Reihe von Worker-Prozessen, um das tatsächliche Speichern/Abrufen von Daten von der Festplatte durchzuführen.
Das Kapitel Ich bin derzeit bei der Einführung einer DIY-Prozess-Registrierung, um einen robusteren Überwachungsbaum zu implementieren, indem die Mitarbeiter sich bei der Registrierung registrieren lassen und der Datenbankprozess den Mitarbeiter mit der Registrierung durchsucht, so dass beide Parteien überwacht werden können und wird immer noch nach einem Fehler arbeiten.
Als Elixir 1.4 herauskam, las ich über das Modul Registry
in den Patchnotes, also dachte ich, ich könnte die App umgestalten und das verwenden. Jetzt stellt sich heraus, dass der Datenbankprozess nicht wirklich wissen muss, aus welchem Ordner die Datenbank Daten speichert. Also nahm ich den mkdir_p!
Anruf von diesem Modul und dachte darüber nach, wo man es setzt. Zwei Optionen in den Sinn kommen:
- Die
DatabaseWorker
- Die
DatabaseWorkerSupervisor
Ich persönlich bevorzuge den zweiten Ansatz, da die ganze app gebunden ist sowieso zum Absturz zu bringen, wenn der Benutzer keine Zugriffsrechte auf die hat Persistenzordner. Aber ich bin mir nicht ganz sicher, ob es in Ordnung ist, Logik in einen Supervisor zu bringen.
Ist Logik in einen Supervisor schlechten Stil oder akzeptabel je nach Situation? Wenn es ein schlechter Stil ist, wo setze ich eine Startlogik, die ich nicht wiederholen will, wenn ein Prozess abstürzt?
Mein Supervisor-Code:
defmodule Todo.DatabaseWorkerSupervisor do
use Supervisor
def start_link(db_folder) do
Supervisor.start_link(__MODULE__, db_folder)
end
def init(db_folder) do
File.mkdir_p!(db_folder)
processes =
for worker_id <- 1..3 do
worker(Todo.DatabaseWorker, [db_folder, worker_id], id: {:dbworker, worker_id})
end
supervise(processes, strategy: :one_for_one)
end
end
Ich wählte diese Antwort, da sie direkt die ursprüngliche Frage beantwortet. Beachten Sie jedoch, dass [diese Antwort] (http://stackoverflow.com/a/43519122/4050456) sehr sinnvoll ist, wenn die Datenbank auch ein GenServer sein soll. –