#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-порты необходимо закрыть, прежде чем можно будет открыть другие, но как это сделать, вероятно, следует задать в новом вопросе со Скотти на видном месте в названии.