Dynamic redirects shouldn't be cached. This especially causes a problem
with redirection to the login page, since trying to actually access the
page the user logged in to see can get them redirected back to the login
page on some browsers.
This patch adds headers to prevent caching of all redirects, which isn't
ideal, but better than allowing caching of all of them.
The following HelloWorld app was used as benchmark:
data HelloWorld = HelloWorld
mkYesod "HelloWorld" [parseRoutes|
/ HomeR GET
|]
instance Yesod HelloWorld where
-- makeSessionBackend = const $ return Nothing
getHomeR = return . RepPlain . toContent $ "Hello World!"
main :: IO ()
main = warp 8080 HelloWorld
The benchmark was tested with httperf under the following
environments:
[vanilla-nosession] Released yesod-core 1.1.1.1, but without sessions.
[vanilla-session] Released yesod-core 1.1.1.1 (with sessions).
[faster-session-1] With patch 065e33a, "Faster, leaner
implementation of putTime/getTime".
[faster-session-2] With this commit.
Performance results:
A) Testing with:
httperf --hog --client=0/1 --server=localhost \
--port=8080 --uri=/ --rate=1000 \
--send-buffer=4096 --recv-buffer=16384 \
--num-conns=100 --wsess=1000,60,1 \
--burst-length=20 --session-cookie
Results:
vanilla-nosession: 19187.7 req/s (0.1 ms/req)
vanilla-session: 2523.3 req/s (0.4 ms/req)
faster-session-1: 2933.5 req/s (0.3 ms/req)
faster-session-2: 2957.5 req/s (0.3 ms/req)
This test benchmarks both saving and loading the session.
Interestingly, this commit provides only a small performance
increase.
B) Testing with:
httperf --hog --client=0/1 --server=localhost \
--port=8080 --uri=/ --rate=1000 \
--send-buffer=4096 --recv-buffer=16384 \
--num-conns=100 --num-calls=1000 \
--burst-length=20
Results:
vanilla-nosession: 43548.7 req/s (0.0 ms/req)
vanilla-session: 3609.4 req/s (0.3 ms/req)
faster-session-1: 3454.9 req/s (0.3 ms/req)
faster-session-2: 3786.9 req/s (0.3 ms/req)
This test benchmarks only saving the session. Strangely,
faster-session-1 was worse than vanilla-session (while
isolated tests show that the new putTime should be +70x
faster). However, there is a non-negligible performance
increase on faster-session-2.
Benchmark on my computer (per call, includes runPut/runGet):
old putTime: 5658 ns +/- 224ns
new putTime: 821 ns +/- 24ns (7x faster)
old getTime: 7228 ns +/- 126ns
new getTime: 99 ns +/- 4ns (73x faster!!)
Besides, the old format used 25 raw bytes (33.3 bytes on the
base64 output), while the new one uses 8 bytes (10.6 bytes on the
base64 output).