«Застревание» с использованием STM

#haskell #stm

#haskell #stm

Вопрос:

У меня есть следующее приложение Scotty, которое пытается использовать STM для подсчета количества обработанных вызовов API:

 {-# LANGUAGE OverloadedStrings #-}

module Main where

import Web.Scotty
import Data.Monoid (mconcat)
import Control.Concurrent.STM
import Control.Monad.IO.Class

main :: IO ()
main = do
  counter <- newTVarIO 0
  scotty 3000 $
    get "/:word" $ do
      liftIO $ atomically $ do
        counter' <- readTVar counter
        writeTVar counter (counter'   1)
      liftIO $ do
        counter' <- atomically (readTVar counter)
        print counter'
      beam <- param "word"
      html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]
  

Я «тестирую нагрузку» API следующим образом:

 ab -c 100 -n 100000 http://127.0.0.1:3000/z
  

Однако API обслуживает примерно около 16 тысяч запросов, а затем «застревает» — ab останавливается с ошибкой apr_socket_recv: Operation timed out (60) .

Я думаю, что неправильно использую STM, но не уверен, что я делаю неправильно. Есть предложения?

Комментарии:

1. Сколько процессора использует ваш сервер, когда он «застревает»?

Ответ №1:

Быстрое предположение здесь. 16 000 — это примерно количество доступных TCP-портов. Возможно ли, что вы не закрыли ни одного соединения и, следовательно, исчерпали открытые порты для ab ?

Комментарии:

1. да, вот и все! Спасибо! все эти соединения находятся в TIME_WAIT состоянии. означает ли это, что scotty неправильно закрывает соединения?

2. Итак, каково решение?

3. похоже, что wrk (вместо ab ) не вызывает этой проблемы.

4. @firefrorefiddle, я не совсем уверен. Я нажал, потому что потратил много времени на изучение STM, а не Скотти. Я знаю, что TCP-порты необходимо закрыть, прежде чем можно будет открыть другие, но как это сделать, вероятно, следует задать в новом вопросе со Скотти на видном месте в названии.