2012-04-12 11 views
93

Ich hatte einen Daemon gemacht, der eine sehr primitive Form von ipc (Telnet und sendete eine Zeichenfolge, die bestimmte Wörter in einer bestimmten Reihenfolge hatte) verwendet. Ich riss es heraus und verwende jetzt JSON, um Nachrichten an einen Yesod Server zu übergeben. Allerdings gab es einige Dinge, die ich an meinem Design wirklich mochte, und ich bin mir nicht sicher, was meine Entscheidungen jetzt sind.Ausnahmen in Yesod

Hier ist, was ich tat:

buildManager :: Phase -> IO() 
buildManager phase = do 
    let buildSeq = findSeq phase 
     jid = JobID $ pack "8" 
     config = MkConfig $ Just jid 
    flip C.catch exceptionHandler $ 
    runReaderT (sequence_ $ buildSeq <*> stages) config 
    -- ^^ I would really like to keep the above line of code, or something like it. 
    return() 

jede Funktion in buildSeq so ausgesehen

foo :: Stage -> ReaderT Config IO() 

data Config = MkConfig (Either JobID Product) BaseDir JobMap 

JobMap ist ein TMVar Map, die Informationen über aktuelle Aufträge verfolgt.

so jetzt, was ich habe Handlers sind, dass alle diese aussehen

foo :: Handler RepJson 

foo stellt einen Befehl für meine Daemon kann jeder Handler ein anderes JSON-Objekt zu verarbeiten hat.

Ich möchte ein JSON-Objekt senden, das Erfolg darstellt, und ein anderes JSON-Objekt, das Informationen über eine Ausnahme enthält.

würde ich foo s Helferfunktion nutzen zu können wie ein Either zurückzukehren, aber ich bin nicht sicher, wie ich das, plus die Fähigkeit, Auswertung meiner Liste von Aktionen zu beenden, buildSeq.

Hier ist die einzige Wahl, die ich

sehen

1) stellen Sie sicher, exceptionHandler in Handler ist. Setzen Sie JobMap in den Datensatz App. Mit getYesod den entsprechenden Wert in JobMap ändern angibt Details über die Ausnahme, auf die zugegriffen werden kann, dann durch foo

Gibt es einen besseren Weg?

Was sind meine anderen Möglichkeiten?

Edit: Für Klarheit, werde ich die Rolle von Handler RepJson erklären. Der Server benötigt eine Möglichkeit, Befehle wie buildstopreport zu akzeptieren. Der Client benötigt eine Möglichkeit, die Ergebnisse dieser Befehle zu kennen. Ich habe JSON als Medium gewählt, mit dem Server und Client miteinander kommunizieren. Ich benutze den Handler-Typ nur um den JSON zu verwalten und nicht mehr.

Antwort

9

Philosophisch gesehen möchten Sie in der Haskell/Yesod-Welt die Werte weiterleiten, anstatt sie rückwärts zu senden. Anstatt also die Handler einen Wert zurückgeben zu lassen, rufen Sie sie zum nächsten Schritt im Prozess auf, um eine Ausnahme zu erzeugen.

Denken Sie daran, dass Sie eine beliebige Anzahl zukünftiger Aktionen in einem einzigen Objekt bündeln können, sodass Sie ein Fortsetzungsobjekt an Ihre Handler und Foos weitergeben können, das ihnen im Grunde sagt: "Nachdem Sie fertig sind, führen Sie diesen Makroblock aus." Auf diese Weise können sie nichtig sein und nichts zurückgeben.

+0

Danke für Ihre Einsicht, Tyler Durden. –