Haskell — узкое место сокета домена Unix от PHP?

Я пишу микросервисный фреймворк для работы вместе с PHP-сайтом. Я написал его и протестировал на своем локальном компьютере (OSX), и он работает очень хорошо. Он будет принимать данные, считывать их как ByteString, анализировать их в данных на Haskell с помощью Aeson и выполнять определенные действия с этими данными. У меня это общение через доменные сокеты Unix.

Я проверил это на моей локальной системе, выполнив curl в php-файл localhost, который связывается с программой на Haskell. Он смог отправить / получить / распечатать информацию 10000 раз за 2 минуты.

Когда я перенес это на рабочий сервер и реализовал то же самое с PHP на той стороне, начали происходить некоторые странные вещи. Программа на Haskell работает, однако где-то ее ловят и, кажется, она зависает все большее время. Сначала он висит на 0,1 секунды дольше, чем должен, и он просто продолжает расти и подниматься. Примерно через минуту получения 10+ запросов в секунду время ожидания составляет почти 8 секунд. Я убедился, что это не та база данных, которая работает медленно по какой-либо причине, сравнивая время вызова Haskell через сокет с текущим временем (прямо перед вызовом базы данных).

Вот моя основная функция:

import Network.Socket

main :: IO ()
main = do
removeSocketFile socketName
resource <- defaultResources
withSocketsDo $ do
sock <- socket AF_UNIX Stream 0
bind sock $ SockAddrUnix socketName
chmodSocket socketName
putStrLn $ "Created socket file at " ++ socketName
listen sock maxListenQueue
catch
(handleSocket sock resource)
(\e -> do
putStrLn $ show (e :: AsyncException)
close sock
putStrLn "Closed socket"removeSocketFile socketName
)

И это код, который обрабатывает сокеты и все:

import Network.Socket
import Network.Socket.ByteString as NB
import Data.ByteString as B
import Data.Char as C

handleSocket :: Socket -> ServerResources -> IO ()
handleSocket sock resource = do
(conn,_) <- accept sock
forkIO $ processConn conn resource
handleSocket sock resource

processConn :: Socket -> ServerResources -> IO ()
processConn conn resource = do
msg <- NB.recv conn 2048
unless (B.null msg) $ do
let (cmd, payload) = B.break (== (fromIntegral $ C.ord ':')) msg
delegate cmd (B.drop 1 payload) conn resource
return ()

Кто-нибудь видит здесь что-то не так, что может привести к тому, что программа будет вести себя так, как я описал выше? Странно то, что он вообще не ломается, когда я запускаю его на OSX, но когда я ставлю его на Ubuntu 15.10, дела идут не так, как должны.

Я думаю, что они могут быть изолированы от этих функций, потому что они являются единственными, которые имеют дело с любым видом ввода-вывода, кроме базы данных (которая, как я уже заключил, не была проблемой).

Любая помощь приветствуется. Благодарю.

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]