2013-06-20 1 views
2

많은 앱 요청으로 제 3 자 API에서 데이터를 가져 오는 Yesod 앱을 개발 중입니다. 가져온 데이터는 후속 요청 중에 만 사용됩니다. 즉 API 호출을 트리거하는 요청이 설명 선의 완료를 기다리지 않고 완료 될 수 있습니다.별도의 'App'및 'BackgroundJobs'패키지를위한 레이아웃

주어진 데이터 조각 xyz을 두 번 가져오고 저장하지 않는 것이 중요하지만, 여러 클라이언트가 동시에 xyz에 관심을 갖게되는 것이 중요합니다. xyz이 이미 가져 왔는지 여부를 확인하기 위해 데이터베이스에 쿼리하는 각 앱 스레드가있는 경우 겸손한 규모에서도 동시성 관련 문제를 보게됩니다. 동시성 관련 무결성 문제를 처리하기위한 코드를 재미있게 작성하지 않아도 모든 사례를 모두 포함했는지 확신 할 수는 없겠지만 비싼 데이터베이스 쿼리를 이런 식으로 남용하는 것은 바람직하지 않습니다.

하나 이상의 'background worker'유형 프로세스가 가입 할 AMQP 대기열에 모든 App 스레드에서 요청 ("xyz 데이터가 가져와 졌는지 확인하십시오")을 게시하는 것이 좋은 대안 인 것처럼 보입니다. .

this thread Greg Weber는 두 패키지가 모두 '내 영구 계층'을 종속성으로 갖는 이중 패키지 레이아웃을 제안합니다. 그는 심볼릭 링크 나 hs-source-dir을 사용하여 'Persistent layer'코드의 두 복사본을 유지하는 것을 피할 수 있다고 언급했습니다.

그레그가 묘사하고있는 것을 나에게 완벽하게 이해시켜 주지만, 나는 하스켈에게 상대적으로 새롭고, 세부 사항을 파악하는 데 다소 시간이 걸릴 까봐 두렵다. 누군가 좀 더 자세히 설명해 줄 수 있습니까?

  • 패키지 디렉토리를 어떻게 배치해야합니까? (정확히 어떤 파일이 내 지속 레이어를 구성합니까?)
  • .cabal 파일은 어떻게 표시되어야합니까?
  • 그런 식으로 배치되면 내 (스캐 폴드 사이트) 소스 파일이 영구 모델을 가져 오는 방식을 변경해야합니까?

또 다른 부분은 다음과 같습니다. 어떻게 BackgroundJobs 프로세스를 작성 하시겠습니까? Yesod의 비계를 제외하고는 제작 하스켈 ​​코드를 쓰지 않았습니다. 광범위한 윤곽을 잡으려고합니다. 메시지 대기열에 가입하고 각 메시지가 나올 때마다 콜 아웃/처리/저장을 수행하지만 그 중에는 걱정할 필요가 있습니다. main을 작성합니다. 설명 선이 끝날 때까지 대기하는 동안 프로세스가 차단되지 않도록 수동으로 포킹해야합니까?

감사합니다.

답변

1

Erik이 제안한 일반적인 접근 방식을 사용하여 시작 블록을 벗어났습니다. 이제 제 2의 executable 블록을 스캐 폴딩 된 프로젝트 .cabal 파일에 추가했습니다.실행 환경이 플래그를 기대도록 수정 -

{-# LANGUAGE OverloadedStrings #-} 
module Main where 

import Import 
import Yesod.Default.Config 
import qualified Database.Persist 
import qualified Database.Persist.Store as DPS (runPool, createPoolConfig, loadConfig, applyEnv) 
import Settings 
import Model 
import Data.Conduit (runResourceT) 
import Control.Monad.Logger (runStdoutLoggingT) 
import Debug.Trace 
import Data.Text as T 

runQueries = do 
    res <- getBy $ UniqueFoo "bar" 
    trace ("\nresult: " ++ show res ++ "\n\n") $ return() 

main :: IO() 
main = do 
    conf <- (fromArgs parseExtra) 
    dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf) 
       DPS.loadConfig >>= DPS.applyEnv 
    p <- DPS.createPoolConfig (dbconf :: Settings.PersistConfig) 
    runStdoutLoggingT $ runResourceT $ DPS.runPool dbconf runQueries p 

I가 this Yesod wiki entry의 첫 번째 예에 근거 : 여기 (에릭의 제제 "daemon.hs")에 대응하는 소스 파일이다.

+0

그건 그렇고, 이것은 예를 들어 1.19를 사용하고있었습니다. 이후 1.2 버전으로 업데이트되었으며이 코드에 몇 가지 작은 조정이 필요했습니다. 모두 쉽고 분명했습니다. –

2

웹 응용 프로그램과 데이터를 수집하고 웹 응용 프로그램과 공유하는 데이터베이스에 삽입하는 별도의 데몬 프로세스로 구성된 응용 프로그램이 있습니다.

기본적으로 동일한 소스 코드 트리에 모든 코드가 있으며 이라는 코드와 daemon.hs 코드라는 두 파일이 있습니다. 그런 다음 cabal 파일을 정의하고 두 개의 개별 실행 파일을 작성합니다.

불행히도 코드를 내 직업으로하고있는 내부 프로젝트로 공유 할 수 없습니다.