2016-01-04 4 views
6

UPDATEYesod rüsteten Website langsame Datenbankpool Verbindung lösen

ich den Beweis dafür mit einem konkreten Projekt vom Gerüst erstellt vereinfacht - Sie können es hier ansehen: https://github.com/tetigi/yesod-bug-test

die Readme-Folgen Einrichten des Repos und Replizieren des Problems! Thanks :)

ORIGINAL POST

Ich habe eine einfache Website mit yesod zu erstellen kürzlich versucht - in einem bestimmten Handler, es ein paar rundb macht Anrufe (Auswahl und einige Werte in ein Einfügen ~ 200 Artikel DB). Bei mittlerer Auslastung, z. B. beim schnellen Laden der Seite in einem Browser, beginnt die Seite zu hängen.

Bei der Fehlersuche habe ich festgestellt, dass die yesod-App die Verbindungen zum DB-Pool nicht rechtzeitig freigibt und darauf wartet, dass sie freigegeben werden. Um correborate dies fand ich die anderen folgende Dinge:

  • Reduzierung des DB-Pool 2 gab mir ein Einfrieren nach nur ein paar Klicks
  • Der Standard (10) fror nach ca. 5 Sekunden klicken
  • den DB-Pool 100 Zunehmende gab mir mehr viel Zeit klicken, bis zu etwa 10 bis 15 Sekunden schnelles klicken
  • das Problem ist das gleiche, ob ich postgres oder sQLite
  • In postgres verwenden, war es möglich, um die 'COMMIT' Transaktionen zu sehen, die sich im Laufe der Zeit stapeln
  • Ich vermisse hier
  • Diese Transaktionen würden schließlich im Laufe der Zeit verschwinden und die Website als Reaktion wieder

Gibt es etwas sein würde? Die Webseite macht nichts kompliziertes, wie der folgende Ausschnitt zeigt. Irgendwelche Ideen? Wie es aussieht, wird die Website für mehrere Benutzer nicht nutzbar sein, bis ich einen Weg finde, dies zu beheben!

Ich verwende die standardgerüstete yesod-Anwendung über Stapel, wie in der Dokumentation empfohlen.

Prost!

Luke

Beispiel-Handler-Code (gekürzt)

getCompareR :: Handler Html 
getCompareR = do 

    -- Get all entities from the db. Throws error if < 2 elems in the DB. 
    entities <- fmap (\xs -> assert (length xs >= 2) xs) $ runDB $ selectList [] [] 

    -- Pick an entity at random 
    Entity _ thisThingEntity <- liftIO $ runRVar (choice entities) DevRandom 

    -- Pull out everything NOT the thing we just picked 
    otherEntities <- runDB $ selectList [ComparisonHash !=. (comparisonHash thisThingEntity)] [] 

    -- Pick one at random 
    Entity _ thatThingEntity <- liftIO $ runRVar (choice otherEntities) DevRandom 

    -- Some stuff including some inserts 
    -- ... 
    -- ... 

    runDB $ sequence [update thisId [ComparisonElo =. thisElo], update thatId [ComparisonElo =. thatElo]] 

    -- Start laying out the webpage 
    defaultLayout $ do 
     -- Fill in the rest with compare.hamlet 
     $(widgetFile "compare") 

Antwort

3

Das Problem liegt in Data.Random - Ersetzen des choice Anruf mit so etwas wie:

import System.Random (randomRIO) 

... 

-- Pick an entity at random 
randomInt1 <- liftIO $ randomRIO (0, length entities -1) 
let Entity _ thisThingEntity = entities !! randomInt1 

Fest alles und wir werden nicht mehr langsamer. Nicht wirklich sicher, warum Data.Random das tut, aber zumindest funktioniert es jetzt!

Eine weitere interessante Sache zu beachten - das Problem ist nicht unter Mac OS X, nur auf Linux-Aromen (CentOS, Arch, Ubuntu, die wir probiert haben)