on master help sign in
using time-manager in warp.
commit93b97fda2941e2439e4c28067ad7dfc2f425ff21 authorKazu Yamamoto <kazu@iij.ad.jp> dateThu 23 May 2019, 16:53 (7 years ago) parentc3160e4
12 files changed+39−192
warp/Network/Wai/Handler/Warp.hs+1−1 warp/Network/Wai/Handler/Warp/HTTP2/Manager.hs+1−1 warp/Network/Wai/Handler/Warp/HTTP2/Sender.hs+1−1 warp/Network/Wai/Handler/Warp/HTTP2/Worker.hs+2−3 warp/Network/Wai/Handler/Warp/Internal.hs+3−2 warp/Network/Wai/Handler/Warp/Request.hs+1−1 warp/Network/Wai/Handler/Warp/Response.hs+1−1 warp/Network/Wai/Handler/Warp/Run.hs+1−1 warp/Network/Wai/Handler/Warp/Settings.hs+1−1 warp/Network/Wai/Handler/Warp/Timeout.hs−153 warp/Network/Wai/Handler/Warp/Types.hs+1−1 warp/warp.cabal+26−26
warp/Network/Wai/Handler/Warp.hs+1−1
@@ -124,6 +124,7 @@ import qualified Data.Vault.Lazy as Vault
124124import qualified Network.HTTP.Types as H
125125import Network.Socket (SockAddr)
126126import Network.Wai (Request, Response, vault)
127+import System.TimeManager
127128
128129import Network.Wai.Handler.Warp.FileInfoCache
129130import Network.Wai.Handler.Warp.HTTP2.Request (getHTTP2Data, setHTTP2Data, modifyHTTP2Data)
@@ -133,7 +134,6 @@ import Network.Wai.Handler.Warp.Request
133134import Network.Wai.Handler.Warp.Response (warpVersion)
134135import Network.Wai.Handler.Warp.Run
135136import Network.Wai.Handler.Warp.Settings
136−import Network.Wai.Handler.Warp.Timeout
137137import Network.Wai.Handler.Warp.Types hiding (getFileInfo)
138138import Network.Wai.Handler.Warp.WithApplication
139139
warp/Network/Wai/Handler/Warp/HTTP2/Manager.hs+1−1
@@ -19,10 +19,10 @@ import Data.Foldable
1919import Data.IORef
2020import Data.Set (Set)
2121import qualified Data.Set as Set
22+import qualified System.TimeManager as T
2223
2324import Network.Wai.Handler.Warp.Imports
2425import Network.Wai.Handler.Warp.Settings
25−import qualified Network.Wai.Handler.Warp.Timeout as T
2626
2727----------------------------------------------------------------
2828
warp/Network/Wai/Handler/Warp/HTTP2/Sender.hs+1−1
@@ -22,7 +22,7 @@ import qualified System.IO as IO
2222#else
2323import Network.Wai.Handler.Warp.FdCache
2424import Network.Wai.Handler.Warp.SendFile (positionRead)
25−import qualified Network.Wai.Handler.Warp.Timeout as T
25+import qualified System.TimeManager as T
2626#endif
2727
2828import Network.Wai.Handler.Warp.Buffer
warp/Network/Wai/Handler/Warp/HTTP2/Worker.hs+2−3
@@ -23,8 +23,8 @@ import qualified Network.HTTP.Types as H
2323import Network.HTTP2
2424import Network.HTTP2.Priority
2525import Network.Wai
26−import qualified Network.Wai.Handler.Warp.Timeout as Timeout
2726import Network.Wai.Internal (Response(..), ResponseReceived(..), ResponseReceived(..), getRequestBodyChunk)
27+import qualified System.TimeManager as T
2828
2929import Network.Wai.Handler.Warp.FileInfoCache
3030import Network.Wai.Handler.Warp.HTTP2.EncodeFrame
@@ -36,7 +36,6 @@ import Network.Wai.Handler.Warp.Imports hiding (insert)
3636import Network.Wai.Handler.Warp.Request (pauseTimeoutKey)
3737import qualified Network.Wai.Handler.Warp.Response as R
3838import qualified Network.Wai.Handler.Warp.Settings as S
39−import qualified Network.Wai.Handler.Warp.Timeout as T
4039import Network.Wai.Handler.Warp.Types
4140
4241----------------------------------------------------------------
@@ -253,7 +252,7 @@ worker ctx@Context{inputQ,controlQ} set app responder tm = do
253252 bs <- body
254253 T.resume th
255254 return bs
256− !vaultValue = Vault.insert pauseTimeoutKey (Timeout.pause th) $ vault req
255+ !vaultValue = Vault.insert pauseTimeoutKey (T.pause th) $ vault req
257256 !req' = req { vault = vaultValue, requestBody = body' }
258257 mr <- E.try $ app req' $ responder ii' reqvt tcont strm req'
259258 case mr of
warp/Network/Wai/Handler/Warp/Internal.hs+3−2
@@ -53,7 +53,7 @@ module Network.Wai.Handler.Warp.Internal (
5353 -- resumed as soon as we return from user code.
5454 --
5555 -- * Every time data is successfully sent to the client, the timeout is tickled.
56− , module Network.Wai.Handler.Warp.Timeout
56+ , module System.TimeManager
5757 -- * File descriptor cache
5858 , module Network.Wai.Handler.Warp.FdCache
5959 -- * File information cache
@@ -69,6 +69,8 @@ module Network.Wai.Handler.Warp.Internal (
6969 , windowsThreadBlockHack
7070 ) where
7171
72+import System.TimeManager
73+
7274import Network.Wai.Handler.Warp.Buffer
7375import Network.Wai.Handler.Warp.Date
7476import Network.Wai.Handler.Warp.FdCache
@@ -80,6 +82,5 @@ import Network.Wai.Handler.Warp.Response
8082import Network.Wai.Handler.Warp.Run
8183import Network.Wai.Handler.Warp.SendFile
8284import Network.Wai.Handler.Warp.Settings
83−import Network.Wai.Handler.Warp.Timeout
8485import Network.Wai.Handler.Warp.Types
8586import Network.Wai.Handler.Warp.Windows
warp/Network/Wai/Handler/Warp/Request.hs+1−1
@@ -24,11 +24,11 @@ import qualified Data.Vault.Lazy as Vault
2424import qualified Network.HTTP.Types as H
2525import Network.Socket (SockAddr)
2626import Network.Wai
27−import qualified Network.Wai.Handler.Warp.Timeout as Timeout
2827import Network.Wai.Handler.Warp.Types
2928import Network.Wai.Internal
3029import Prelude hiding (lines)
3130import System.IO.Unsafe (unsafePerformIO)
31+import qualified System.TimeManager as Timeout
3232
3333import Network.Wai.Handler.Warp.Conduit
3434import Network.Wai.Handler.Warp.FileInfoCache
warp/Network/Wai/Handler/Warp/Response.hs+1−1
@@ -30,6 +30,7 @@ import qualified Network.HTTP.Types.Header as H
3030import Network.Wai
3131import Network.Wai.Internal
3232import qualified Paths_warp
33+import qualified System.TimeManager as T
3334
3435import Network.Wai.Handler.Warp.Buffer (toBuilderBuffer)
3536import qualified Network.Wai.Handler.Warp.Date as D
@@ -39,7 +40,6 @@ import Network.Wai.Handler.Warp.IO (toBufIOWith)
3940import Network.Wai.Handler.Warp.Imports
4041import Network.Wai.Handler.Warp.ResponseHeader
4142import Network.Wai.Handler.Warp.Settings
42−import qualified Network.Wai.Handler.Warp.Timeout as T
4343import Network.Wai.Handler.Warp.Types
4444
4545-- $setup
warp/Network/Wai/Handler/Warp/Run.hs+1−1
@@ -25,6 +25,7 @@ import Network.Wai
2525import Network.Wai.Internal (ResponseReceived (ResponseReceived))
2626import System.Environment (lookupEnv)
2727import System.Timeout (timeout)
28+import qualified System.TimeManager as T
2829
2930import Network.Wai.Handler.Warp.Buffer
3031import Network.Wai.Handler.Warp.Counter
@@ -40,7 +41,6 @@ import Network.Wai.Handler.Warp.Request
4041import Network.Wai.Handler.Warp.Response
4142import Network.Wai.Handler.Warp.SendFile
4243import Network.Wai.Handler.Warp.Settings
43−import qualified Network.Wai.Handler.Warp.Timeout as T
4444import Network.Wai.Handler.Warp.Types
4545
4646
warp/Network/Wai/Handler/Warp/Settings.hs+1−1
@@ -21,9 +21,9 @@ import Network.Wai
2121import qualified Paths_warp
2222import System.IO (stderr)
2323import System.IO.Error (ioeGetErrorType)
24+import System.TimeManager
2425
2526import Network.Wai.Handler.Warp.Imports
26−import Network.Wai.Handler.Warp.Timeout
2727import Network.Wai.Handler.Warp.Types
2828
2929-- | Various Warp server settings. This is purposely kept as an abstract data
warp/Network/Wai/Handler/Warp/Timeout.hsdeleted−153
@@ -1,153 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−{-# LANGUAGE DeriveDataTypeable #-}
3−
4−module Network.Wai.Handler.Warp.Timeout (
5− -- ** Types
6− Manager
7− , TimeoutAction
8− , Handle
9− -- ** Manager
10− , initialize
11− , stopManager
12− , killManager
13− , withManager
14− -- ** Registration
15− , register
16− , registerKillThread
17− -- ** Control
18− , tickle
19− , cancel
20− , pause
21− , resume
22− -- ** Exceptions
23− , TimeoutThread (..)
24− ) where
25−
26−import Control.Concurrent (myThreadId)
27−import qualified Control.Exception as E
28−import Control.Reaper
29−import Data.Typeable (Typeable)
30−import Data.IORef (IORef)
31−import qualified Data.IORef as I
32−
33−----------------------------------------------------------------
34−
35−-- | A timeout manager
36−type Manager = Reaper [Handle] Handle
37−
38−-- | An action to be performed on timeout.
39−type TimeoutAction = IO ()
40−
41−-- | A handle used by 'Manager'
42−data Handle = Handle !(IORef TimeoutAction) !(IORef State)
43−
44−data State = Active -- Manager turns it to Inactive.
45− | Inactive -- Manager removes it with timeout action.
46− | Paused -- Manager does not change it.
47− | Canceled -- Manager removes it without timeout action.
48−
49−----------------------------------------------------------------
50−
51−-- | Creating timeout manager which works every N micro seconds
52−-- where N is the first argument.
53−initialize :: Int -> IO Manager
54−initialize timeout = mkReaper defaultReaperSettings
55− { reaperAction = mkListAction prune
56− , reaperDelay = timeout
57− }
58− where
59− prune m@(Handle actionRef stateRef) = do
60− state <- I.atomicModifyIORef' stateRef (\x -> (inactivate x, x))
61− case state of
62− Inactive -> do
63− onTimeout <- I.readIORef actionRef
64− onTimeout `E.catch` ignoreAll
65− return Nothing
66− Canceled -> return Nothing
67− _ -> return $ Just m
68−
69− inactivate Active = Inactive
70− inactivate x = x
71−
72−----------------------------------------------------------------
73−
74−-- | Stopping timeout manager with onTimeout fired.
75−stopManager :: Manager -> IO ()
76−stopManager mgr = E.mask_ (reaperStop mgr >>= mapM_ fire)
77− where
78− fire (Handle actionRef _) = do
79− onTimeout <- I.readIORef actionRef
80− onTimeout `E.catch` ignoreAll
81−
82−ignoreAll :: E.SomeException -> IO ()
83−ignoreAll _ = return ()
84−
85−-- | Killing timeout manager immediately without firing onTimeout.
86−killManager :: Manager -> IO ()
87−killManager = reaperKill
88−
89−----------------------------------------------------------------
90−
91−-- | Registering a timeout action.
92−register :: Manager -> TimeoutAction -> IO Handle
93−register mgr onTimeout = do
94− actionRef <- I.newIORef onTimeout
95− stateRef <- I.newIORef Active
96− let h = Handle actionRef stateRef
97− reaperAdd mgr h
98− return h
99−
100−-- | Registering a timeout action of killing this thread.
101−registerKillThread :: Manager -> TimeoutAction -> IO Handle
102−registerKillThread m onTimeout = do
103− -- If we hold ThreadId, the stack and data of the thread is leaked.
104− -- If we hold Weak ThreadId, the stack is released. However, its
105− -- data is still leaked probably because of a bug of GHC.
106− -- So, let's just use ThreadId and release ThreadId by
107− -- overriding the timeout action by "cancel".
108− tid <- myThreadId
109− -- First run the timeout action in case the child thread is masked.
110− register m $ onTimeout `E.finally` E.throwTo tid TimeoutThread
111−
112−data TimeoutThread = TimeoutThread
113− deriving Typeable
114−instance E.Exception TimeoutThread where
115− toException = E.asyncExceptionToException
116− fromException = E.asyncExceptionFromException
117−instance Show TimeoutThread where
118− show TimeoutThread = "Thread killed by Warp's timeout reaper"
119−
120−----------------------------------------------------------------
121−
122−-- | Setting the state to active.
123−-- 'Manager' turns active to inactive repeatedly.
124−tickle :: Handle -> IO ()
125−tickle (Handle _ stateRef) = I.writeIORef stateRef Active
126−
127−-- | Setting the state to canceled.
128−-- 'Manager' eventually removes this without timeout action.
129−cancel :: Handle -> IO ()
130−cancel (Handle actionRef stateRef) = do
131− I.writeIORef actionRef (return ()) -- ensuring to release ThreadId
132− I.writeIORef stateRef Canceled
133−
134−-- | Setting the state to paused.
135−-- 'Manager' does not change the value.
136−pause :: Handle -> IO ()
137−pause (Handle _ stateRef) = I.writeIORef stateRef Paused
138−
139−-- | Setting the paused state to active.
140−-- This is an alias to 'tickle'.
141−resume :: Handle -> IO ()
142−resume = tickle
143−
144−----------------------------------------------------------------
145−
146−-- | Call the inner function with a timeout manager.
147−withManager :: Int -- ^ timeout in microseconds
148− -> (Manager -> IO a)
149− -> IO a
150−withManager timeout f = do
151− -- FIXME when stopManager is available, use it
152− man <- initialize timeout
153− f man
warp/Network/Wai/Handler/Warp/Types.hs+1−1
@@ -10,12 +10,12 @@ import Data.IORef (IORef, readIORef, writeIORef, newIORef)
1010import Data.Typeable (Typeable)
1111import Foreign.Ptr (Ptr)
1212import System.Posix.Types (Fd)
13+import qualified System.TimeManager as T
1314
1415import qualified Network.Wai.Handler.Warp.Date as D
1516import qualified Network.Wai.Handler.Warp.FdCache as F
1617import qualified Network.Wai.Handler.Warp.FileInfoCache as I
1718import Network.Wai.Handler.Warp.Imports
18−import qualified Network.Wai.Handler.Warp.Timeout as T
1919
2020----------------------------------------------------------------
2121
warp/warp.cabal+26−26
@@ -42,19 +42,20 @@ Library
4242 , case-insensitive >= 0.2
4343 , containers
4444 , ghc-prim
45+ , hashable
46+ , http-date
4547 , http-types >= 0.11
46− , iproute >= 1.3.1
4748 , http2 >= 1.6 && < 1.7
49+ , iproute >= 1.3.1
4850 , simple-sendfile >= 0.2.7 && < 0.3
49− , unix-compat >= 0.2
50− , wai >= 3.2 && < 3.3
51− , text
51+ , stm >= 2.3
5252 , streaming-commons >= 0.1.10
53+ , text
54+ , time-manager
55+ , unix-compat >= 0.2
5356 , vault >= 0.3
54− , stm >= 2.3
57+ , wai >= 3.2 && < 3.3
5558 , word8
56− , hashable
57− , http-date
5859 if impl(ghc < 8)
5960 Build-Depends: semigroups
6061 if flag(network-bytestring)
@@ -95,7 +96,6 @@ Library
9596 Network.Wai.Handler.Warp.Run
9697 Network.Wai.Handler.Warp.SendFile
9798 Network.Wai.Handler.Warp.Settings
98− Network.Wai.Handler.Warp.Timeout
9999 Network.Wai.Handler.Warp.Types
100100 Network.Wai.Handler.Warp.Windows
101101 Network.Wai.Handler.Warp.WithApplication
@@ -171,7 +171,6 @@ Test-Suite spec
171171 Network.Wai.Handler.Warp.Run
172172 Network.Wai.Handler.Warp.SendFile
173173 Network.Wai.Handler.Warp.Settings
174− Network.Wai.Handler.Warp.Timeout
175174 Network.Wai.Handler.Warp.Types
176175 Network.Wai.Handler.Warp.Windows
177176 Network.Wai.Handler.Warp.WithApplication
@@ -182,37 +181,38 @@ Test-Suite spec
182181
183182 Ghc-Options: -Wall -threaded
184183 Build-Depends: base >= 4.8 && < 5
184+ , HUnit
185+ , QuickCheck
185186 , array
187+ , async
186188 , auto-update
187189 , bsb-http-chunked < 0.1
188190 , bytestring >= 0.9.1.4
189191 , case-insensitive >= 0.2
192+ , containers
193+ , directory
190194 , ghc-prim
195+ , hashable
196+ , hspec >= 1.3
191197 , http-client
198+ , http-date
192199 , http-types >= 0.8.5
200+ , http2 >= 1.6 && < 1.7
193201 , iproute >= 1.3.1
194202 , lifted-base >= 0.1
203+ , network
204+ , process
195205 , simple-sendfile >= 0.2.4 && < 0.3
206+ , stm >= 2.3
207+ , streaming-commons >= 0.1.10
208+ , text
209+ , time
210+ , time-manager
196211 , transformers >= 0.2.2
197212 , unix-compat >= 0.2
198− , wai >= 3.2 && < 3.3
199− , network
200− , HUnit
201− , QuickCheck
202− , hspec >= 1.3
203− , time
204− , text
205− , streaming-commons >= 0.1.10
206− , async
207213 , vault
208− , stm >= 2.3
209− , directory
210− , process
211− , containers
212− , http2 >= 1.6 && < 1.7
214+ , wai >= 3.2 && < 3.3
213215 , word8
214− , hashable
215− , http-date
216216 -- Build-Tool-Depends: hspec-discover:hspec-discover
217217 if impl(ghc < 8)
218218 Build-Depends: semigroups
@@ -233,7 +233,6 @@ Benchmark parser
233233 Network.Wai.Handler.Warp.HashMap
234234 Network.Wai.Handler.Warp.Imports
235235 Network.Wai.Handler.Warp.MultiMap
236− Network.Wai.Handler.Warp.Timeout
237236 Network.Wai.Handler.Warp.Types
238237 HS-Source-Dirs: bench .
239238 Build-Depends: base >= 4.8 && < 5
@@ -246,6 +245,7 @@ Benchmark parser
246245 , http-types
247246 , network
248247 , network
248+ , time-manager
249249 , unix-compat
250250 if impl(ghc < 8)
251251 Build-Depends: semigroups