Comments (10)
We probably want to fully-evaluate the result though (and not just to WHNF), given that the goal of timeout is to terminate the computation if it takes too long regardless of the reason.
from snap-core.
Pinging @gregorycollins
from snap-core.
Here's a full reproducer @gregorycollins :
{-# LANGUAGE OverloadedStrings #-}
import Snap.Core
import Snap.Http.Server
import qualified Data.List as L
main = quickHttpServe $ route [
("hmm", hmm)
]
hmm :: Snap ()
hmm = do
setTimeout 5
writeBS $ if L.find (==1) (repeat 0) == Just 1 then "A" else "B"
Then try e.g. curl 'localhost:8000/hmm'
from snap-core.
That's the way GHC RTS works. GHC does all thread related operations on memory allocation, and your example does not allocate memory thanks to stream fusion.
from snap-core.
The fact that this times out correctly with $!
suggests it's not completely uninterruptible. Rather, the timeout is being enforced around the handler, but not the evaluation of the thunk to produce the response after the handler returns.
from snap-core.
I talked with @gregorycollins about this. We don't see a way to fix this given the way the GHC RTS works as pointed out by @sopvop. It's almost certainly not appropriate for Snap to all values to WHNF before using them because it's certainly not just writeBS
that is susceptible to this. Such a change would have an unknown impact on virtually every Snap application ever written. All this for a problem that you already know how to work around with a simple $!
. The vast majority of real-world handlers will have memory allocation and this will not be an issue. This seems like one of those places where you just have to understand how the RTS works and code accordingly to make your long-running pure computations are something that the RTS can break out of.
from snap-core.
Also, if Snap reduced all values to WHNF, I don't think that would solve the problem because your program could still inject a pure non-terminating subexpression anywhere deeper in the evaluation tree that would trigger this. Taking the next obvious step of fully evaluating everything everywhere would impose an NFData
constraint everywhere which would definitely not be acceptable. This is a problem that has to be solved at the user level, not the snap level.
from snap-core.
@mightybyte @gregorycollins sorry if this is a little hand-wavy, but isn't it possible to force evaluation "later in the pipeline", i.e. when Snap constructs the response ByteString? (Maybe in/around processRequest
or runServerHandler
in snap-server/src/Snap/Internal/Http/Server/Session.hs
?)
That way, you don't need to force (or deepseq) anything other than the final response ByteString (which already has an NFData
instance if it's needed), and the timeout duration refers simply to the entire lifecycle of the request.
A practical benefit of making pure timeouts work is that currently specially-crafted requests can force vulnerable handlers to run basically forever.
from snap-core.
@tom-bop If you open a PR on snap-server, that will make it much easier to have a more concrete conversation about the idea.
from snap-core.
Thanks, added here: snapframework/snap-server#118
from snap-core.
Related Issues (20)
- Add 422 Unprocessable Entity HOT 1
- Invariant documented for `rqPathInfo` doesn't always hold HOT 2
- test failure, 1.0.3.2, header order Access-Control-Allow-Headers, guix i386
- Support for GHC-8.8 HOT 11
- "Snap supports ghc versions from 7.4 through 8.0" HOT 3
- `getHeader` doesn't trim trailing OWS
- Add support for the SameSite cookie attribute HOT 2
- randomIO issue HOT 6
- Do Params handle percent decoding? HOT 1
- Test failure with hashable 1.3.1.0 HOT 3
- Support newer time library HOT 1
- How to use the (MonadBaseControl IO) instance of Snap?
- Compatibility with hashable-1.4 HOT 2
- Compatibility with GHC 9.2 HOT 1
- Compatibility with transformers 0.6 HOT 1
- Get CI working again
- IO exception: A web handler threw an exception. Details: no value HOT 2
- Building with GHC 9.2.x
- won't compile on 9.2.5 HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from snap-core.