Hello, I wonder how to pass “Reuse Port” option into the Warp settings so that on server restart, those “Address in use” error never appears. I use “CTRL+C” to close the current running Warp server, and use stack run to run it.
import Network.Wai.Handler.Warp (setPort, defaultSettings)
warpOpts = setPort 8080 defaultSettings
Error:
Network.Socket.bind: resource busy (Address already in use)
Might be possible to reuse the port, but i would have tried to make ctrl-c do a clean shutdown.
1 Like
nh2
April 22, 2023, 6:59pm
3
Here’s how you can set SO_REUSEADDR
to allow re-using the port immediately.
Get a port yourself using bindPortTCP
.
Use setSocketOption socket ReuseAddr 1
to allow immediate reuse.
Use your own port via Warp.runSettingsSocket
.
#!/usr/bin/env stack
-- stack script --compile --resolver lts-20.18 --package warp --package wai --package http-types --package streaming-commons --package network
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS -Wall #-}
module Main where
import Control.Exception (bracket)
import Data.Streaming.Network (bindPortTCP)
import Network.Wai (responseLBS)
import qualified Network.Socket as Socket
import Network.HTTP.Types.Status (status200)
import qualified Network.Wai.Handler.Warp as Warp
main :: IO ()
main = do
bracket (bindPortTCP 1234 "*") Socket.close' $ \socket -> do
putStrLn "Got socket, setting SO_REUSEADDR"
Socket.setSocketOption socket Socket.ReuseAddr 1
Warp.runSettingsSocket Warp.defaultSettings socket $ \_req respond -> do
putStrLn "responding to request"
respond $ responseLBS status200 [] "hi"
Run with e.g. stack Main.hs
.
Test with curl 'http://localhost:1234'
.
2 Likes