yesodweb / wai

Haskell Web Application Interface
MIT License
834 stars 262 forks source link

High CPU usage with websocketsOr (Windows only) #433

Open andrewhn opened 9 years ago

andrewhn commented 9 years ago

Hi,

Hoping this belongs here and not in websockets. I've run into trouble writing a http/ws application and boiled it down to the following example. Instructions to reproduce are in the comment. The problem is, when I disconnect a websocket there's a ~5-10 second lag and CPU usage jumps and persists. The issue only seems to occur with the addition of websocketsOr - the runServer function doesn't exhibit the same CPU hungry behaviour.

Same code on a linux box works with no issue. I used stack new to scaffold and all lts package versions. Can post cabal file if it will help.

Thanks

{-# LANGUAGE OverloadedStrings #-}

{-
  To reproduce:

  Windows only
  run code
  Open chrome/ff/etc
  In console
    x = new WebSocket("ws://localhost:8080")
    x.close()
  Wait ~10 seconds
  Look at CPU usage
-}

module Main where

import Network.Wai (Application, responseLBS)
import Network.HTTP.Types (status404)
import qualified Data.Text as T
import Network.Wai.Handler.Warp (run)
import qualified Network.WebSockets as WS
import Network.Wai.Handler.WebSockets (websocketsOr)
import Control.Concurrent (MVar, modifyMVar_, newMVar)
import Control.Monad (forever, forM_)
import Control.Exception (handle)

wsApp ::  WS.ServerApp
wsApp pending = do
    conn <- WS.acceptRequest pending
    WS.forkPingThread conn 30
    forever (WS.receiveData conn :: IO T.Text)

app :: Application
app request respond = respond $ responseLBS status404 [] "Not found"

main :: IO ()
main = do
    -- works fine
    --WS.runServer "0.0.0.0" 8080 wsApp

    -- does not work
    run 8080 $ websocketsOr WS.defaultConnectionOptions wsApp app
creichert commented 9 years ago

Thanks for the report.

What lts version are you using? What version of wai-websockets, websockets, wai, and warp? (stack exec -- ghc-pkg list, not sure how to translate this to windows).

On Mon, Sep 14 2015, andrewhn notifications@github.com wrote:

Hi,

Hoping this belongs here and not in websockets. I've run into trouble writing a http/ws application and boiled it down to the following example. Instructions to reproduce are in the comment. The problem is, when I disconnect a websocket there's a ~5-10 second lag and CPU usage jumps and persists. The issue only seems to occur with the addition of websocketsOr - the runServer function doesn't exhibit the same CPU hungry behaviour.

Same code on a linux box works with no issue. I used stack new to scaffold and all lts package versions. Can post cabal file if it will help.

Thanks

{-# LANGUAGE OverloadedStrings #-}

{-
  To reproduce:

  Windows only
  run code
  Open chrome/ff/etc
  In console
    x = new WebSocket("ws://localhost:8080")
    x.close()
  Wait ~10 seconds
  Look at CPU usage
-}

module Main where

import Network.Wai (Application, responseLBS)
import Network.HTTP.Types (status404)
import qualified Data.Text as T
import Network.Wai.Handler.Warp (run)
import qualified Network.WebSockets as WS
import Network.Wai.Handler.WebSockets (websocketsOr)
import Control.Concurrent (MVar, modifyMVar_, newMVar)
import Control.Monad (forever, forM_)
import Control.Exception (handle)

wsApp ::  WS.ServerApp
wsApp pending = do
    conn <- WS.acceptRequest pending
    WS.forkPingThread conn 30
    forever (WS.receiveData conn :: IO T.Text)

app :: Application
app request respond = respond $ responseLBS status404 [] "Not found"

main :: IO ()
main = do
    -- works fine
    --WS.runServer "0.0.0.0" 8080 wsApp

    -- does not work
    run 8080 $ websocketsOr WS.defaultConnectionOptions wsApp app

Reply to this email directly or view it on GitHub: https://github.com/yesodweb/wai/issues/433

andrewhn commented 9 years ago
    wai-websockets-3.0.0.6
    warp-3.1.3
    websockets-0.9.5.0
    wai-3.0.3.0

On Windows 8.1 Pro x64. Full output (FYI stack exec ghc-pkg list works the same on windows):

C:\Program Files\Haskell Platform\7.10.2\lib\package.conf.d:
    Cabal-1.22.4.0
    GLURaw-1.5.0.1
    GLUT-2.7.0.1
    HTTP-4000.2.20
    HUnit-1.2.5.2
    ObjectName-1.1.0.0
    OpenGL-2.12.0.1
    OpenGLRaw-2.5.1.0
    QuickCheck-2.8.1
    StateVar-1.1.0.0
    Win32-2.3.1.0
    array-0.5.1.0
    async-2.0.2
    attoparsec-0.13.0.0
    base-4.8.1.0
    bin-package-db-0.0.0.0
    binary-0.7.5.0
    rts-1.0
    bytestring-0.10.6.0
    case-insensitive-1.2.0.4
    cgi-3001.2.2.2
    containers-0.5.6.2
    deepseq-1.4.1.1
    directory-1.2.2.0
    exceptions-0.8.0.2
    fgl-5.5.1.0
    filepath-1.4.0.0
    (ghc-7.10.2)
    ghc-prim-0.4.0.0
    hashable-1.2.3.3
    haskeline-0.7.2.1
    haskell-src-1.0.2.0
    hoopl-3.10.0.2
    hpc-0.6.0.2
    hscolour-1.23
    html-1.0.1.2
    integer-gmp-1.0.0.0
    mtl-2.2.1
    multipart-0.1.2
    network-2.6.2.0
    network-uri-2.6.0.3
    old-locale-1.0.0.7
    old-time-1.1.0.3
    parallel-3.2.0.6
    parsec-3.1.9
    pretty-1.1.2.0
    primitive-0.6
    process-1.2.3.0
    random-1.1
    regex-base-0.93.2
    regex-compat-0.95.1
    regex-posix-0.95.2
    scientific-0.3.3.8
    split-0.2.2
    stm-2.4.4
    syb-0.5.1
    template-haskell-2.10.0.0
    text-1.2.1.1
    tf-random-0.5
    time-1.5.0.1
    transformers-0.4.2.0
    transformers-compat-0.4.0.4
    unordered-containers-0.2.5.1
    vector-0.10.12.3
    xhtml-3000.2.1
    zlib-0.5.4.2

C:\Users\andrewn\AppData\Roaming\stack\snapshots\x86_64-windows\lts-3.4\7.10.2\pkgdb:
    SHA-1.6.4.2
    StateVar-1.1.0.1
    adjunctions-4.2.1
    aeson-0.8.0.2
    aeson-pretty-0.7.2
    ansi-terminal-0.6.2.2
    ansi-wl-pprint-0.6.7.3
    appar-0.1.4
    asn1-encoding-0.9.0
    asn1-parse-0.9.1
    asn1-types-0.3.0
    attoparsec-0.12.1.6
    auto-update-0.1.2.2
    base-orphans-0.4.4
    base16-bytestring-0.1.1.6
    base64-bytestring-1.0.0.1
    bifunctors-5
    blaze-builder-0.4.0.1
    blaze-html-0.8.1.0
    blaze-markup-0.7.0.2
    blaze-textual-0.2.1.0
    byteable-0.1.1
    byteorder-1.0.4
    bytestring-builder-0.10.6.0.0
    case-insensitive-1.2.0.4
    cereal-0.4.1.1
    cmdargs-0.10.13
    comonad-4.2.7.2
    conduit-1.2.5
    conduit-extra-1.1.9.1
    connection-0.2.5
    contravariant-1.3.2
    cookie-0.4.1.6
    cryptohash-0.11.6
    cryptohash-conduit-0.1.1
    cryptonite-0.6
    data-default-class-0.0.1
    digest-0.0.1.2
    distributive-0.4.4
    dlist-0.7.1.2
    easy-file-0.2.1
    entropy-0.3.7
    expiring-cache-map-0.0.5.4
    fast-logger-2.4.1
    file-embed-0.0.9
    free-4.12.1
    generics-sop-0.1.1.2
    hashable-1.2.3.3
    hex-0.1.2
    hourglass-0.2.9
    http-client-0.4.21
    http-client-tls-0.2.2
    http-conduit-2.1.8
    http-date-0.0.6.1
    http-types-0.8.6
    http2-1.0.4
    iproute-1.5.0
    kan-extensions-4.2.2
    lens-4.12.3
    lifted-base-0.2.3.6
    memory-0.7
    mime-types-0.1.0.6
    mmorph-1.0.4
    monad-control-1.0.0.4
    mwc-random-0.13.3.2
    nats-1
    network-2.6.2.1
    network-info-0.2.0.7
    network-uri-2.6.0.3
    optparse-applicative-0.11.0.2
    parsec-3.1.9
    pem-0.2.2
    postgresql-libpq-0.9.1.1
    postgresql-simple-0.4.10.0
    prelude-extras-0.4
    profunctors-5.1.1
    reflection-2
    resource-pool-0.2.3.2
    resourcet-1.1.6
    scientific-0.3.3.8
    semigroupoids-5.0.0.4
    semigroups-0.16.2.2
    simple-sendfile-0.2.21
    socks-0.5.4
    streaming-commons-0.1.12.1
    stringsearch-0.3.6.6
    tagged-0.8.1
    tagsoup-0.13.3
    text-1.2.1.3
    tls-1.3.2
    transformers-base-0.4.4
    unix-compat-0.4.1.4
    unordered-containers-0.2.5.1
    uuid-1.3.11
    uuid-types-1.0.2
    vault-0.3.0.4
    void-0.7
    wai-3.0.3.0
    wai-app-static-3.1.1
    wai-extra-3.0.10
    wai-logger-2.2.4.1
    wai-middleware-static-0.7.0.1
    wai-websockets-3.0.0.6
    warp-3.1.3
    websockets-0.9.5.0
    word8-0.1.2
    x509-1.6.0
    x509-store-1.6.0
    x509-system-1.6.0
    x509-validation-1.6.0
    zip-archive-0.2.3.7

C:\Users\andrewn\Documents\ws-test4\.stack-work\install\x86_64-windows\lts-3.4\7.10.2\pkgdb:
    ws-test4-0.1.0.0
istandleet commented 8 years ago

Here to reiterate the same problem. Windows 10

webSockets $ (runConduit ((mapOutput (TL.decodeUtf8 . A.encode) parserConduit) =$= sinkWSText))

...stack-work\install\3c6cd252\pkgdb: HDBC-2.4.0.1 HDBC-odbc-2.5.0.0 adjunctions-4.3 aeson-0.9.0.1 aeson-compat-0.3.2.0 aeson-pretty-0.7.2 attoparsec-0.13.0.2 authenticate-1.3.3.1 bifunctors-5.2 blaze-builder-0.4.0.2 blaze-html-0.8.1.1 blaze-markup-0.7.0.3 bson-0.3.2.1 case-insensitive-1.2.0.6 cassava-0.4.5.0 chunked-data-0.2.0 comonad-4.2.7.2 concurrent-extra-0.7.0.10 conduit-combinators-1.0.3.1 conduit-extra-1.1.13.1 contravariant-1.4 convertible-1.1.1.0 cookie-0.4.2 cryptohash-conduit-0.1.1 css-text-0.1.2.1 dlist-instances-0.1 email-validate-2.2.0 fast-logger-2.4.6 free-4.12.4 hamlet-1.2.0 hashable-1.2.4.0 hashtables-1.2.1.0 hjsmin-0.1.5.3 http-api-data-0.2.2 http-client-0.4.28 http-client-tls-0.2.4 http-conduit-2.1.10 http-date-0.0.6.1 http-types-0.9 http2-1.4.5 kan-extensions-4.2.3 keys-3.11 language-javascript-0.5.14.7 mime-mail-0.4.11 mime-types-0.1.0.7 monad-logger-0.3.18 mongoDB-2.0.10 mono-traversable-0.10.2 network-uri-2.6.1.0 nonce-1.0.2 ntServer-0.1.0 parsec-3.1.9 path-pieces-0.2.1 persistent-2.2.4.1 persistent-mongoDB-2.1.4 persistent-odbc-0.2.0.1 persistent-template-2.1.8 pointed-4.2.0.2 profunctors-5.2 psqueues-0.2.2.1 resource-pool-0.2.3.2 scientific-0.3.4.6 semigroupoids-5.0.1 semigroups-0.18.1 shakespeare-2.0.8.2 simple-sendfile-0.2.21 streaming-commons-0.1.15.4 tagsoup-0.13.9 tagstream-conduit-0.5.5.3 text-1.2.2.1 unordered-containers-0.2.5.1 vault-0.3.0.6 vector-instances-3.3.1 void-0.7.1 wai-3.2.1 wai-app-static-3.1.5 wai-extra-3.0.15.1 wai-logger-2.2.7 wai-websockets-3.0.0.8 warp-3.2.2 websockets-0.9.6.1 xml-conduit-1.3.4.2 xml-types-0.3.6 xss-sanitize-0.3.5.7 yaml-0.8.17.1 yesod-1.4.3 yesod-auth-1.4.13.2 yesod-core-1.4.20.2 yesod-form-1.4.7.1 yesod-persistent-1.4.0.5 yesod-static-1.5.0.3 yesod-static-angular-0.1.7 yesod-table-2.0.3 yesod-websockets-0.2.4 zip-conduit-0.2.2.2