7

Simon Marlowは、 Haskell eXchange 2012 で高性能同時実行の講演を行いました。時間の制約により、単純な同時チャット サーバーに関するセクションをスキップしました。省略されたコンテンツに興味を持った Web 検索で、サーバー アプリケーションに関する同様のスライドとGitHub 上の実装が見つかりました。

スライド 33読み取り

話を戻します…

talk :: Server -> Handle -> IO ()
talk server@Server{..} handle = do
    hSetNewlineMode handle universalNewlineMode
    hSetBuffering handle LineBuffering
    readName
  where
    readName = do
      hPutStrLn handle "What is your name?"
      name <- hGetLine handle
      m <- checkAddClient server name handle
      case m of
         Nothing -> do
           hPrintf handle "The name %s is in use" name
           readName
         Just client -> do
           runClient server client
              `finally` removeClient server name

厳密には、 と の間の穴を塞ぐ必要がcheckAddClientありfinallyます (注を参照してください…)

前に、スライド 3で「注記の第 14 章」について言及していますが、これは彼の今後の本を指していると思われます。checkAddClientとの間の同期クラックとは何finallyですか? どうすればプラグインできますか?

前述の実装ではmask、from Control.Exception を使用しています。これが修正である場合、タイミングの悪い例外がパーティーを台無しにするシナリオは何ですか?

...
readName = do
  hPutStrLn handle "What is your name?"
  name <- hGetLine handle
  if null name
     then readName
     else mask $ \restore -> do
            ok <- checkAddClient server name handle
            case ok of
              Nothing -> restore $ do
                 hPrintf handle
                    "The name %s is in use, please choose another\n" name
                 readName
              Just client ->
                 restore (runClient server client)
                   `finally` removeClient server name
4

2 に答える 2

2

すべての成功checkAddClientremoveClient. 下部のステートメントは、アクションが開始された場合に が実行finallyされることのみを保証します。removeClientrunClient

ただし、そのコードが非同期例外を受け取る可能性がある場所の最後checkAddClientと最初の間に短いウィンドウがあります。runClientその場合、コマンドfinallyを登録する機会がありません。removeClientこれは、サイモンが言及している同期クラックです。

解決策は、デフォルトで非同期例外をマスクし、特定の場所 (つまり、 によってラップされたアクションrestore) にのみ表示されるようにすることです。これにより、前述のクラックがシールされます。

于 2013-01-27T01:53:25.967 に答える
0

これをしたらどうなりますかcheckAddClient

checkAddClient server name handle = do
  addClient server name handle
  return undefined

ケースがその引数を評価するまで、例外はトリガーされず、removeClient呼び出されることはありません。

しかし、正直なところ、私は非同期例外を理解していません。

于 2013-01-27T04:27:15.817 に答える