2

多くのアプリ リクエストによってサードパーティ API からデータが取得される Yesod アプリを開発しています。フェッチされたデータは、後続のリクエストでのみ使用されます。つまり、API コールアウトをトリガーするリクエストは、コールアウトが終了するのを待たずに終了できます。

特定のデータxyzを 2 回取得して保存しないことが重要ですが、アプリの性質上、複数のクライアントがxyz同時に関心を持つことがよくあります。xyz各アプリ スレッドがデータベースにクエリを実行して、既にフェッチされているかどうかを確認すると、小規模な規模でも同時実行性に関連する問題が発生し始めます。同時実行性に関連する整合性の問題を処理するために大量のコードを作成したとしても (楽しくないし、すべてのケースを網羅したかどうかを確認するのは難しいでしょう)、高価なデータベース クエリをこのように悪用するのは悪い習慣です。

1 つ以上の「バックグラウンド ワーカー」タイプのプロセスがサブスクライブする AMQP キューに、すべてのアプリ スレッドがリクエストを発行する (「xyz データがフェッチされていることを確認してください」) ようにすることは、私には良い代替手段と思われます。

このスレッドで Greg Weber は、両方のパッケージが依存関係として「my Persistent layer」を持つデュアル パッケージ レイアウトを提案しています。hs-source-dir彼は、「永続層」コードの 2 つのコピーを維持することを避けるために、シンボリック リンクまたは s を使用できると述べています。

大まかに言えば、Greg が説明していることは私には完全に理にかなっていますが、私は Haskell に比較的慣れていないため、詳細を理解するのに時間がかかるのではないかと心配しています。誰かが私のためにそれをより詳細に説明できますか?

  • パッケージ ディレクトリはどのように配置する必要がありますか? (具体的にどのファイルが持続層を構成していますか?)
  • .cabal ファイルはどのようになりますか?
  • それらがそのようにレイアウトされたら、(スキャフォールディングされたサイト) ソース ファイルが永続モデルをインポートする方法を変更する必要がありますか?

もう 1 つの部分は次のとおりです。BackgroundJobs プロセスをどのように記述することをお勧めしますか? 私は、Yesod の足場を除いて、製品版の Haskell コードを書いたことはありません。私はそれを大まかなアウトラインで取得します-mainメッセージキューにサブスクライブし、各メッセージでコールアウト/処理/保存を行う .コールアウトが終了するのを待っている間にプロセスがブロックされないようにするには?

どうもありがとう。

4

2 に答える 2

2

webapp と、データを収集して webapp と共有するデータベースに挿入する別のデーモン プロセスで構成されるアプリケーションがあります。

基本的に、すべてのコードを同じソース コード ツリーに配置し、 を定義する 2 つのファイルを持ってmain :: IO ()webapp.hsますdaemon.hs。次に、cabal ファイルで 2 つの個別の実行可能ファイルを定義してビルドします。

残念ながら、私が日常業務で行っている内部プロジェクトとしてコードを共有することはできません。

于 2013-06-21T00:26:21.457 に答える
1

エリックが提案した一般的なアプローチを使用して、開始ブロックから外れています-executable足場プロジェクトの.cabalファイルに2番目のブロックを追加しました。対応するソース ファイルはdaemon.hs次のとおりです (Erik の定式化では " ")。

{-# 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

この Yesod wiki エントリの最初の例に基づいて、実行可能ファイルが環境フラグを期待するように変更しました。

于 2013-06-22T00:42:00.150 に答える