Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
H
hikaru
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
TO
hikaru
Commits
82102e70
Verified
Commit
82102e70
authored
4 years ago
by
jan.hamal.dvorak
Browse files
Options
Downloads
Patches
Plain Diff
Add a simple cache to MonadAction
Signed-off-by:
Jan Hamal Dvořák
<
mordae@anilinux.org
>
parent
0364018a
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
lib/Hikaru/Action.hs
+67
-11
67 additions, 11 deletions
lib/Hikaru/Action.hs
with
67 additions
and
11 deletions
lib/Hikaru/Action.hs
+
67
−
11
View file @
82102e70
...
@@ -83,6 +83,11 @@ module Hikaru.Action
...
@@ -83,6 +83,11 @@ module Hikaru.Action
,
getLanguages
,
getLanguages
,
setLanguages
,
setLanguages
-- ** Cacheing
,
withCache
,
dropCache
,
dropCaches
-- ** Finalizing
-- ** Finalizing
,
registerFinalizer
,
registerFinalizer
...
@@ -100,6 +105,7 @@ where
...
@@ -100,6 +105,7 @@ where
import
qualified
Data.ByteString.Lazy
as
LBS
import
qualified
Data.ByteString.Lazy
as
LBS
import
qualified
Data.Text.Lazy
as
LT
import
qualified
Data.Text.Lazy
as
LT
import
qualified
Network.Wai.Parse
as
Parse
import
qualified
Network.Wai.Parse
as
Parse
import
qualified
Data.Map.Strict
as
Map
import
Control.Monad.Trans
import
Control.Monad.Trans
import
Control.Monad.Trans.Resource
import
Control.Monad.Trans.Resource
...
@@ -108,30 +114,30 @@ where
...
@@ -108,30 +114,30 @@ where
import
Data.ByteString
(
ByteString
,
length
)
import
Data.ByteString
(
ByteString
,
length
)
import
Data.String.Conversions
import
Data.String.Conversions
import
Data.Text
(
Text
)
import
Data.Text
(
Text
)
import
Hikaru.Media
import
Hikaru.Types
import
Lucid
import
Lucid
import
Network.HTTP.Types.Header
import
Network.HTTP.Types.Header
import
Network.HTTP.Types.Method
import
Network.HTTP.Types.Method
import
Network.HTTP.Types.Status
import
Network.HTTP.Types.Status
import
Network.Wai
import
Network.Wai
import
Web.Cookie
import
Web.Cookie
import
Hikaru.Media
import
Hikaru.Types
-- |
-- |
--
Inside the
'MonadAction' the original 'Request'
is available and we can
-- 'MonadAction'
provides access to
the original 'Request'
and means to
--
query it for information while building a fresh
'Response' to send out.
--
build a
'Response' to send out.
--
--
-- * Request header
is
always fully parsed.
-- * Request header
s are
always fully parsed.
-- * Body is left untouched until you decide what to do with it.
-- * Body is left untouched until you decide what to do with it.
--
--
-- Be careful not to blow
up
your memory usage by reading a multi-gigabyte
-- Be careful not to blow
out
your memory usage by reading a multi-gigabyte
-- attachment into a strict ByteString or something.
-- attachment into a strict ByteString or something
similar
.
--
--
class
(
MonadIO
m
)
=>
MonadAction
m
where
class
(
MonadIO
m
)
=>
MonadAction
m
where
-- |
-- |
-- Return the action environment, including the 'Request' object,
cached
-- Return the action environment, including the 'Request' object,
-- content from the user and the pending 'Response'.
--
cached
content from the user and the pending 'Response'.
--
--
getActionEnv
::
m
ActionEnv
getActionEnv
::
m
ActionEnv
...
@@ -188,6 +194,7 @@ where
...
@@ -188,6 +194,7 @@ where
,
aeBodyLimit
::
IORef
Int64
,
aeBodyLimit
::
IORef
Int64
,
aeBodyCounter
::
IORef
Int64
,
aeBodyCounter
::
IORef
Int64
,
aeLanguages
::
IORef
[
Text
]
,
aeLanguages
::
IORef
[
Text
]
,
aeCache
::
IORef
(
Map
.
Map
Text
Dynamic
)
}
}
...
@@ -258,6 +265,7 @@ where
...
@@ -258,6 +265,7 @@ where
<*>
newIORef
(
10
*
1024
*
1024
)
<*>
newIORef
(
10
*
1024
*
1024
)
<*>
newIORef
0
<*>
newIORef
0
<*>
newIORef
[]
<*>
newIORef
[]
<*>
newIORef
Map
.
empty
-- Inspecting Request ------------------------------------------------------
-- Inspecting Request ------------------------------------------------------
...
@@ -271,7 +279,7 @@ where
...
@@ -271,7 +279,7 @@ where
-- |
-- |
-- Obtain the request method, such as
\"
GET
\"
or
\"
POST
\"
.
-- Obtain the request method, such as
@
GET
@
or
@
POST
@
.
--
--
getMethod
::
(
MonadAction
m
)
=>
m
Method
getMethod
::
(
MonadAction
m
)
=>
m
Method
getMethod
=
requestMethod
<$>
getRequest
getMethod
=
requestMethod
<$>
getRequest
...
@@ -816,7 +824,7 @@ where
...
@@ -816,7 +824,7 @@ where
-- values in a sensible way.
-- values in a sensible way.
--
--
-- @
-- @
-- modifyHeader
"
Vary
"
$ maybe "Accept" (<> ", Accept")
-- modifyHeader
'h
Vary
'
$ maybe "Accept" (<> ", Accept")
-- @
-- @
--
--
modifyHeader
::
(
MonadAction
m
)
modifyHeader
::
(
MonadAction
m
)
...
@@ -1025,6 +1033,54 @@ where
...
@@ -1025,6 +1033,54 @@ where
setLanguages
=
setActionField
aeLanguages
setLanguages
=
setActionField
aeLanguages
-- Cacheing ----------------------------------------------------------------
-- |
-- Run the effect only if it was not found in the cache.
--
-- The cache is request-specific and will be dropped after the request
-- has been handled. It can be also dropped manually using 'dropCache'
-- or 'dropCaches'.
--
-- The first time 'withCache' is called with a given key, the resulting
-- value is stored in the cache under that key. Next time, the effect is
-- not executed and the cached value is returned instead.
--
-- Since 'Dynamic' is used under the wraps, reusing the same key with a
-- different type of value is safe and will result in overwriting the
-- old key.
--
withCache
::
(
MonadAction
m
,
Typeable
a
)
=>
Text
->
m
a
->
m
a
withCache
key
makeValue
=
do
cache
<-
getActionField
aeCache
case
fromDynamic
=<<
Map
.
lookup
key
cache
of
Nothing
->
do
value
<-
makeValue
modifyActionField
aeCache
(
Map
.
insert
key
(
toDyn
value
))
return
value
Just
value
->
do
return
value
-- |
-- Drop a single cached value.
--
dropCache
::
(
MonadAction
m
)
=>
Text
->
m
()
dropCache
key
=
do
modifyActionField
aeCache
(
Map
.
delete
key
)
-- |
-- Drop all cached values.
--
dropCaches
::
(
MonadAction
m
)
=>
m
()
dropCaches
=
do
modifyActionField
aeCache
(
const
Map
.
empty
)
-- Finalizing --------------------------------------------------------------
-- Finalizing --------------------------------------------------------------
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment