Skip to content

Commit 0fc5117

Browse files
committed
Support for using deepseq to evaluate batch requests
1 parent 6dc3f39 commit 0fc5117

File tree

3 files changed

+25
-10
lines changed

3 files changed

+25
-10
lines changed

json-rpc-server.cabal

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ synopsis: JSON-RPC 2.0 on the server side.
1111
build-type: Simple
1212
extra-source-files: README.md
1313
cabal-version: >=1.8
14-
tested-with: GHC == 7.0.1, GHC == 7.4.1, GHC == 7.6.2, GHC == 7.6.3, GHC == 7.8.3
14+
tested-with: GHC == 7.0.1, GHC == 7.4.1, GHC == 7.6.2,
15+
GHC == 7.6.3, GHC == 7.8.3, GHC == 7.10.1
1516
description: An implementation of the server side of JSON-RPC 2.0.
1617
See <http://www.jsonrpc.org/specification>. This
1718
library uses 'ByteString' for input and output,
@@ -32,6 +33,7 @@ library
3233
other-modules: Network.JsonRpc.Types
3334
build-depends: base >=4.3 && <4.9,
3435
aeson >=0.6 && <0.9,
36+
deepseq >= 1.1 && <1.5,
3537
bytestring >=0.9 && <0.11,
3638
mtl >=1.1.1 && <2.3,
3739
text >=0.11 && <1.3,

src/Network/JsonRpc/Server.hs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import qualified Data.ByteString.Lazy as B
4343
import qualified Data.Aeson as A
4444
import qualified Data.Vector as V
4545
import qualified Data.HashMap.Strict as H
46+
import Control.DeepSeq (NFData)
4647
import Control.Monad (liftM)
4748
import Control.Monad.Identity (runIdentity)
4849
import Control.Monad.Error (runErrorT, throwError)
@@ -100,13 +101,13 @@ call = callWithBatchStrategy sequence
100101

101102
-- | Handles one JSON-RPC request.
102103
callWithBatchStrategy :: Monad m =>
103-
(forall a . [m a] -> m [a]) -- ^ Function specifying the
104-
-- evaluation strategy.
105-
-> Methods m -- ^ Choice of methods to call.
106-
-> B.ByteString -- ^ JSON-RPC request.
107-
-> m (Maybe B.ByteString) -- ^ The response wrapped in 'Just', or
108-
-- 'Nothing' in the case of a notification,
109-
-- all wrapped in the given monad.
104+
(forall a . NFData a => [m a] -> m [a]) -- ^ Function specifying the
105+
-- evaluation strategy.
106+
-> Methods m -- ^ Choice of methods to call.
107+
-> B.ByteString -- ^ JSON-RPC request.
108+
-> m (Maybe B.ByteString) -- ^ The response wrapped in 'Just', or
109+
-- 'Nothing' in the case of a notification,
110+
-- all wrapped in the given monad.
110111
callWithBatchStrategy strategy fs input = either returnErr callMethod request
111112
where request :: Either RpcError (Either A.Value [A.Value])
112113
request = runIdentity $ runErrorT $ parseVal =<< parseJson input
@@ -147,7 +148,7 @@ lookupMethod name = maybe notFound return . H.lookup name
147148
throwInvalidRpc :: Monad m => Text -> RpcResult m a
148149
throwInvalidRpc = throwError . rpcErrorWithData (-32600) "Invalid JSON-RPC 2.0 request"
149150

150-
batchCall :: Monad m => (forall a. [m a] -> m [a])
151+
batchCall :: Monad m => (forall a. NFData a => [m a] -> m [a])
151152
-> Methods m
152153
-> [A.Value]
153154
-> m (Maybe [Response])

src/Network/JsonRpc/Types.hs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import Data.Aeson ((.=), (.:), (.:?), (.!=))
3232
import Data.Aeson.Types (emptyObject)
3333
import qualified Data.Vector as V
3434
import qualified Data.HashMap.Strict as H
35+
import Control.DeepSeq (NFData, rnf)
3536
import Control.Monad (mplus, when)
3637
import Control.Monad.Error (Error, ErrorT, throwError, strMsg, noMsg)
3738
import Prelude hiding (length)
@@ -136,6 +137,9 @@ instance A.FromJSON Request where
136137

137138
data Response = Response Id (Either RpcError A.Value)
138139

140+
instance NFData Response where
141+
rnf (Response i e) = rnf i `seq` rnf e `seq` ()
142+
139143
instance A.ToJSON Response where
140144
toJSON (Response i result) = A.object pairs
141145
where pairs = [ versionKey .= jsonRpcVersion
@@ -146,6 +150,11 @@ instance A.ToJSON Response where
146150
-- since it changes between aeson-0.6 and 0.7.
147151
data Id = IdString A.Value | IdNumber A.Value | IdNull
148152

153+
instance NFData Id where
154+
rnf (IdString s) = rnf s `seq` ()
155+
rnf (IdNumber n) = rnf n `seq` ()
156+
rnf IdNull = ()
157+
149158
instance A.FromJSON Id where
150159
parseJSON x@(A.String _) = return $ IdString x
151160
parseJSON x@(A.Number _) = return $ IdNumber x
@@ -161,7 +170,10 @@ instance A.ToJSON Id where
161170
data RpcError = RpcError { errCode :: Int
162171
, errMsg :: Text
163172
, errData :: Maybe A.Value }
164-
deriving (Show, Eq)
173+
deriving (Show, Eq)
174+
175+
instance NFData RpcError where
176+
rnf (RpcError e m d) = rnf e `seq` rnf m `seq` rnf d `seq` ()
165177

166178
instance Error RpcError where
167179
noMsg = strMsg "unknown error"

0 commit comments

Comments
 (0)