Skip to content

Commit 701a4ab

Browse files
Adjusted codebase to avoid all warnings, including deprecated Producer/Consumer from conduit. Removed a few unnecessary parentheses too.
Fixed erroneously removed CPP expressions. Removed unused imports. for issue mongodb-haskell#126. Allow optional TLS params Removing superfluous brackets; simplifying a few functions.
1 parent 5980bc1 commit 701a4ab

File tree

9 files changed

+235
-211
lines changed

9 files changed

+235
-211
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ dist/
22
cabal.sandbox.config
33
.cabal-sandbox/
44
.stack-work/
5+
dist-newstyle/*
6+
!dist-newstyle/config

Database/MongoDB/Admin.hs

-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import Control.Applicative ((<$>))
3333
#endif
3434
import Control.Concurrent (forkIO, threadDelay)
3535
import Control.Monad (forever, unless, liftM)
36-
import Control.Monad.Fail(MonadFail)
3736
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
3837
import Data.Maybe (maybeToList)
3938
import Data.Set (Set)

Database/MongoDB/Connection.hs

+21-23
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ module Database.MongoDB.Connection (
1717
Host(..), PortID(..), defaultPort, host, showHostPort, readHostPort,
1818
readHostPortM, globalConnectTimeout, connect, connect',
1919
-- * Replica Set
20-
ReplicaSetName, openReplicaSet, openReplicaSet', openReplicaSetTLS, openReplicaSetTLS',
21-
openReplicaSetSRV, openReplicaSetSRV', openReplicaSetSRV'', openReplicaSetSRV''',
20+
ReplicaSetName, openReplicaSet, openReplicaSet', openReplicaSetTLS, openReplicaSetTLS',
21+
openReplicaSetSRV, openReplicaSetSRV', openReplicaSetSRV'', openReplicaSetSRV''',
2222
ReplicaSet, primary, secondaryOk, routedHost, closeReplicaSet, replSetName
2323
) where
2424

@@ -32,15 +32,13 @@ import Control.Applicative ((<$>))
3232
#endif
3333

3434
import Control.Monad (forM_, guard)
35-
import Control.Monad.Fail(MonadFail)
3635
import System.IO.Unsafe (unsafePerformIO)
3736
import System.Timeout (timeout)
3837
import Text.ParserCombinators.Parsec (parse, many1, letter, digit, char, anyChar, eof,
3938
spaces, try, (<|>))
4039
import qualified Data.List as List
4140

4241

43-
import Control.Monad.Identity (runIdentity)
4442
import Control.Monad.Except (throwError)
4543
import Control.Concurrent.MVar.Lifted (MVar, newMVar, withMVar, modifyMVar,
4644
readMVar)
@@ -149,28 +147,28 @@ openReplicaSet' :: Secs -> (ReplicaSetName, [Host]) -> IO ReplicaSet
149147
-- ^ Open connections (on demand) to servers in replica set. Supplied hosts is seed list. At least one of them must be a live member of the named replica set, otherwise fail. Supplied seconds timeout is used for connect attempts to members.
150148
openReplicaSet' timeoutSecs (rs, hosts) = _openReplicaSet timeoutSecs (rs, hosts, Unsecure)
151149

152-
openReplicaSetTLS :: (ReplicaSetName, [Host]) -> IO ReplicaSet
150+
openReplicaSetTLS :: (ReplicaSetName, [Host]) -> IO ReplicaSet
153151
-- ^ Open secure connections (on demand) to servers in the replica set. Supplied hosts is seed list. At least one of them must be a live member of the named replica set, otherwise fail. The value of 'globalConnectTimeout' at the time of this call is the timeout used for future member connect attempts. To use your own value call 'openReplicaSetTLS'' instead.
154152
openReplicaSetTLS rsSeed = readIORef globalConnectTimeout >>= flip openReplicaSetTLS' rsSeed
155153

156-
openReplicaSetTLS' :: Secs -> (ReplicaSetName, [Host]) -> IO ReplicaSet
154+
openReplicaSetTLS' :: Secs -> (ReplicaSetName, [Host]) -> IO ReplicaSet
157155
-- ^ Open secure connections (on demand) to servers in replica set. Supplied hosts is seed list. At least one of them must be a live member of the named replica set, otherwise fail. Supplied seconds timeout is used for connect attempts to members.
158156
openReplicaSetTLS' timeoutSecs (rs, hosts) = _openReplicaSet timeoutSecs (rs, hosts, Secure)
159157

160158
_openReplicaSet :: Secs -> (ReplicaSetName, [Host], TransportSecurity) -> IO ReplicaSet
161-
_openReplicaSet timeoutSecs (rsName, seedList, transportSecurity) = do
159+
_openReplicaSet timeoutSecs (rsName, seedList, transportSecurity) = do
162160
vMembers <- newMVar (map (, Nothing) seedList)
163161
let rs = ReplicaSet rsName vMembers timeoutSecs transportSecurity
164162
_ <- updateMembers rs
165163
return rs
166164

167-
openReplicaSetSRV :: HostName -> IO ReplicaSet
165+
openReplicaSetSRV :: HostName -> IO ReplicaSet
168166
-- ^ Open /non-secure/ connections (on demand) to servers in a replica set. The seedlist and replica set name is fetched from the SRV and TXT DNS records for the given hostname. The value of 'globalConnectTimeout' at the time of this call is the timeout used for future member connect attempts. To use your own value call 'openReplicaSetSRV''' instead.
169-
openReplicaSetSRV hostname = do
167+
openReplicaSetSRV hostname = do
170168
timeoutSecs <- readIORef globalConnectTimeout
171169
_openReplicaSetSRV timeoutSecs Unsecure hostname
172170

173-
openReplicaSetSRV' :: HostName -> IO ReplicaSet
171+
openReplicaSetSRV' :: HostName -> IO ReplicaSet
174172
-- ^ Open /secure/ connections (on demand) to servers in a replica set. The seedlist and replica set name is fetched from the SRV and TXT DNS records for the given hostname. The value of 'globalConnectTimeout' at the time of this call is the timeout used for future member connect attempts. To use your own value call 'openReplicaSetSRV'''' instead.
175173
--
176174
-- The preferred connection method for cloud MongoDB providers. A typical connecting sequence is shown in the example below.
@@ -180,27 +178,27 @@ openReplicaSetSRV' :: HostName -> IO ReplicaSet
180178
-- > pipe <- openReplicatSetSRV' "cluster#.xxxxx.yyyyy.zzz"
181179
-- > is_auth <- access pipe master "admin" $ auth user_name password
182180
-- > unless (not is_auth) (throwIO $ userError "Authentication failed!")
183-
openReplicaSetSRV' hostname = do
181+
openReplicaSetSRV' hostname = do
184182
timeoutSecs <- readIORef globalConnectTimeout
185183
_openReplicaSetSRV timeoutSecs Secure hostname
186184

187-
openReplicaSetSRV'' :: Secs -> HostName -> IO ReplicaSet
185+
openReplicaSetSRV'' :: Secs -> HostName -> IO ReplicaSet
188186
-- ^ Open /non-secure/ connections (on demand) to servers in a replica set. The seedlist and replica set name is fetched from the SRV and TXT DNS records for the given hostname. Supplied seconds timeout is used for connect attempts to members.
189187
openReplicaSetSRV'' timeoutSecs = _openReplicaSetSRV timeoutSecs Unsecure
190188

191-
openReplicaSetSRV''' :: Secs -> HostName -> IO ReplicaSet
189+
openReplicaSetSRV''' :: Secs -> HostName -> IO ReplicaSet
192190
-- ^ Open /secure/ connections (on demand) to servers in a replica set. The seedlist and replica set name is fetched from the SRV and TXT DNS records for the given hostname. Supplied seconds timeout is used for connect attempts to members.
193191
openReplicaSetSRV''' timeoutSecs = _openReplicaSetSRV timeoutSecs Secure
194192

195-
_openReplicaSetSRV :: Secs -> TransportSecurity -> HostName -> IO ReplicaSet
196-
_openReplicaSetSRV timeoutSecs transportSecurity hostname = do
197-
replicaSetName <- lookupReplicaSetName hostname
198-
hosts <- lookupSeedList hostname
199-
case (replicaSetName, hosts) of
193+
_openReplicaSetSRV :: Secs -> TransportSecurity -> HostName -> IO ReplicaSet
194+
_openReplicaSetSRV timeoutSecs transportSecurity hostname = do
195+
replicaSetName <- lookupReplicaSetName hostname
196+
hosts <- lookupSeedList hostname
197+
case (replicaSetName, hosts) of
200198
(Nothing, _) -> throwError $ userError "Failed to lookup replica set name"
201199
(_, []) -> throwError $ userError "Failed to lookup replica set seedlist"
202-
(Just rsName, _) ->
203-
case transportSecurity of
200+
(Just rsName, _) ->
201+
case transportSecurity of
204202
Secure -> openReplicaSetTLS' timeoutSecs (rsName, hosts)
205203
Unsecure -> openReplicaSet' timeoutSecs (rsName, hosts)
206204

@@ -229,7 +227,7 @@ routedHost :: ((Host, Bool) -> (Host, Bool) -> IO Ordering) -> ReplicaSet -> IO
229227
routedHost f rs = do
230228
info <- updateMembers rs
231229
hosts <- shuffle (possibleHosts info)
232-
let addIsPrimary h = (h, if Just h == statedPrimary info then True else False)
230+
let addIsPrimary h = (h, Just h == statedPrimary info)
233231
hosts' <- mergesortM (\a b -> f (addIsPrimary a) (addIsPrimary b)) hosts
234232
untilSuccess (connection rs Nothing) hosts'
235233

@@ -275,8 +273,8 @@ connection (ReplicaSet _ vMembers timeoutSecs transportSecurity) mPipe host' =
275273
where
276274
conn = modifyMVar vMembers $ \members -> do
277275
let (Host h p) = host'
278-
let conn' = case transportSecurity of
279-
Secure -> TLS.connect h p
276+
let conn' = case transportSecurity of
277+
Secure -> TLS.connect h p
280278
Unsecure -> connect' timeoutSecs host'
281279
let new = conn' >>= \pipe -> return (updateAssocs host' (Just pipe) members, pipe)
282280
case List.lookup host' members of

Database/MongoDB/GridFS.hs

+33-35
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- Author:
22
-- Brent Tubbs <brent.tubbs@gmail.com>
33
-- | MongoDB GridFS implementation
4-
{-# LANGUAGE OverloadedStrings, RecordWildCards, NamedFieldPuns, TupleSections, FlexibleContexts, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, GeneralizedNewtypeDeriving, StandaloneDeriving, TypeSynonymInstances, TypeFamilies, CPP, RankNTypes #-}
4+
{-# LANGUAGE OverloadedStrings, FlexibleContexts, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, TypeFamilies, CPP, RankNTypes #-}
55

66
module Database.MongoDB.GridFS
77
( Bucket
@@ -23,10 +23,8 @@ module Database.MongoDB.GridFS
2323
)
2424
where
2525

26-
import Control.Applicative((<$>))
2726

2827
import Control.Monad(when)
29-
import Control.Monad.Fail(MonadFail)
3028
import Control.Monad.IO.Class
3129
import Control.Monad.Trans(lift)
3230

@@ -64,54 +62,54 @@ openBucket :: (Monad m, MonadIO m) => Text -> Action m Bucket
6462
openBucket name = do
6563
let filesCollection = name `append` ".files"
6664
let chunksCollection = name `append` ".chunks"
67-
ensureIndex $ (index filesCollection ["filename" =: (1::Int), "uploadDate" =: (1::Int)])
65+
ensureIndex $ index filesCollection ["filename" =: (1::Int), "uploadDate" =: (1::Int)]
6866
ensureIndex $ (index chunksCollection ["files_id" =: (1::Int), "n" =: (1::Int)]) { iUnique = True, iDropDups = True }
6967
return $ Bucket filesCollection chunksCollection
7068

7169
data File = File {bucket :: Bucket, document :: Document}
7270

7371
getChunk :: (MonadFail m, MonadIO m) => File -> Int -> Action m (Maybe S.ByteString)
7472
-- ^ Get a chunk of a file
75-
getChunk (File bucket doc) i = do
73+
getChunk (File _bucket doc) i = do
7674
files_id <- B.look "_id" doc
77-
result <- findOne $ select ["files_id" := files_id, "n" =: i] $ chunks bucket
75+
result <- findOne $ select ["files_id" := files_id, "n" =: i] $ chunks _bucket
7876
let content = at "data" <$> result
7977
case content of
8078
Just (Binary b) -> return (Just b)
8179
_ -> return Nothing
8280

8381
findFile :: MonadIO m => Bucket -> Selector -> Action m [File]
8482
-- ^ Find files in the bucket
85-
findFile bucket sel = do
86-
cursor <- find $ select sel $ files bucket
83+
findFile _bucket sel = do
84+
cursor <- find $ select sel $ files _bucket
8785
results <- rest cursor
88-
return $ File bucket <$> results
86+
return $ File _bucket <$> results
8987

9088
findOneFile :: MonadIO m => Bucket -> Selector -> Action m (Maybe File)
9189
-- ^ Find one file in the bucket
92-
findOneFile bucket sel = do
93-
mdoc <- findOne $ select sel $ files bucket
94-
return $ File bucket <$> mdoc
90+
findOneFile _bucket sel = do
91+
mdoc <- findOne $ select sel $ files _bucket
92+
return $ File _bucket <$> mdoc
9593

9694
fetchFile :: MonadIO m => Bucket -> Selector -> Action m File
9795
-- ^ Fetch one file in the bucket
98-
fetchFile bucket sel = do
99-
doc <- fetch $ select sel $ files bucket
100-
return $ File bucket doc
96+
fetchFile _bucket sel = do
97+
doc <- fetch $ select sel $ files _bucket
98+
return $ File _bucket doc
10199

102100
deleteFile :: (MonadIO m, MonadFail m) => File -> Action m ()
103101
-- ^ Delete files in the bucket
104-
deleteFile (File bucket doc) = do
102+
deleteFile (File _bucket doc) = do
105103
files_id <- B.look "_id" doc
106-
delete $ select ["_id" := files_id] $ files bucket
107-
delete $ select ["files_id" := files_id] $ chunks bucket
104+
delete $ select ["_id" := files_id] $ files _bucket
105+
delete $ select ["files_id" := files_id] $ chunks _bucket
108106

109107
putChunk :: (Monad m, MonadIO m) => Bucket -> ObjectId -> Int -> L.ByteString -> Action m ()
110108
-- ^ Put a chunk in the bucket
111-
putChunk bucket files_id i chunk = do
112-
insert_ (chunks bucket) ["files_id" =: files_id, "n" =: i, "data" =: Binary (L.toStrict chunk)]
109+
putChunk _bucket files_id i chunk = do
110+
insert_ (chunks _bucket) ["files_id" =: files_id, "n" =: i, "data" =: Binary (L.toStrict chunk)]
113111

114-
sourceFile :: (MonadFail m, MonadIO m) => File -> Producer (Action m) S.ByteString
112+
sourceFile :: (MonadFail m, MonadIO m) => File -> ConduitT File S.ByteString (Action m) ()
115113
-- ^ A producer for the contents of a file
116114
sourceFile file = yieldChunk 0 where
117115
yieldChunk i = do
@@ -134,19 +132,19 @@ data FileWriter = FileWriter
134132

135133
-- Finalize file, calculating md5 digest, saving the last chunk, and creating the file in the bucket
136134
finalizeFile :: (Monad m, MonadIO m) => Text -> FileWriter -> Action m File
137-
finalizeFile filename (FileWriter chunkSize bucket files_id i size acc md5context md5acc) = do
135+
finalizeFile filename (FileWriter chunkSize _bucket files_id i size acc md5context md5acc) = do
138136
let md5digest = finalizeMD5 md5context (L.toStrict md5acc)
139-
when (L.length acc > 0) $ putChunk bucket files_id i acc
140-
currentTimestamp <- liftIO $ getCurrentTime
137+
when (L.length acc > 0) $ putChunk _bucket files_id i acc
138+
currentTimestamp <- liftIO getCurrentTime
141139
let doc = [ "_id" =: files_id
142140
, "length" =: size
143141
, "uploadDate" =: currentTimestamp
144-
, "md5" =: show (md5digest)
142+
, "md5" =: show md5digest
145143
, "chunkSize" =: chunkSize
146144
, "filename" =: filename
147145
]
148-
insert_ (files bucket) doc
149-
return $ File bucket doc
146+
insert_ (files _bucket) doc
147+
return $ File _bucket doc
150148

151149
-- finalize the remainder and return the MD5Digest.
152150
finalizeMD5 :: MD5Context -> S.ByteString -> MD5Digest
@@ -160,11 +158,11 @@ finalizeMD5 ctx remainder =
160158

161159
-- Write as many chunks as can be written from the file writer
162160
writeChunks :: (Monad m, MonadIO m) => FileWriter -> L.ByteString -> Action m FileWriter
163-
writeChunks (FileWriter chunkSize bucket files_id i size acc md5context md5acc) chunk = do
161+
writeChunks (FileWriter chunkSize _bucket files_id i size acc md5context md5acc) chunk = do
164162
-- Update md5 context
165163
let md5BlockLength = fromIntegral $ untag (blockLength :: Tagged MD5Digest Int)
166164
let md5acc_temp = (md5acc `L.append` chunk)
167-
let (md5context', md5acc') =
165+
let (md5context', md5acc') =
168166
if (L.length md5acc_temp < md5BlockLength)
169167
then (md5context, md5acc_temp)
170168
else let numBlocks = L.length md5acc_temp `div` md5BlockLength
@@ -174,17 +172,17 @@ writeChunks (FileWriter chunkSize bucket files_id i size acc md5context md5acc)
174172
let size' = (size + L.length chunk)
175173
let acc_temp = (acc `L.append` chunk)
176174
if (L.length acc_temp < chunkSize)
177-
then return (FileWriter chunkSize bucket files_id i size' acc_temp md5context' md5acc')
175+
then return (FileWriter chunkSize _bucket files_id i size' acc_temp md5context' md5acc')
178176
else do
179177
let (newChunk, acc') = L.splitAt chunkSize acc_temp
180-
putChunk bucket files_id i newChunk
181-
writeChunks (FileWriter chunkSize bucket files_id (i+1) size' acc' md5context' md5acc') L.empty
178+
putChunk _bucket files_id i newChunk
179+
writeChunks (FileWriter chunkSize _bucket files_id (i+1) size' acc' md5context' md5acc') L.empty
182180

183-
sinkFile :: (Monad m, MonadIO m) => Bucket -> Text -> Consumer S.ByteString (Action m) File
181+
sinkFile :: (Monad m, MonadIO m) => Bucket -> Text -> ConduitT S.ByteString () (Action m) File
184182
-- ^ A consumer that creates a file in the bucket and puts all consumed data in it
185-
sinkFile bucket filename = do
183+
sinkFile _bucket filename = do
186184
files_id <- liftIO $ genObjectId
187-
awaitChunk $ FileWriter defaultChunkSize bucket files_id 0 0 L.empty md5InitialContext L.empty
185+
awaitChunk $ FileWriter defaultChunkSize _bucket files_id 0 0 L.empty md5InitialContext L.empty
188186
where
189187
awaitChunk fw = do
190188
mchunk <- await

Database/MongoDB/Internal/Network.hs

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
-- | Compatibility layer for network package, including newtype 'PortID'
2-
{-# LANGUAGE CPP, GeneralizedNewtypeDeriving, OverloadedStrings #-}
2+
{-# LANGUAGE CPP, OverloadedStrings #-}
33

44
module Database.MongoDB.Internal.Network (Host(..), PortID(..), N.HostName, connectTo,
55
lookupReplicaSetName, lookupSeedList) where
66

7-
87
#if !MIN_VERSION_network(2, 9, 0)
98

109
import qualified Network as N
@@ -20,7 +19,7 @@ import System.IO (Handle, IOMode(ReadWriteMode))
2019
#endif
2120

2221
import Data.ByteString.Char8 (pack, unpack)
23-
import Data.List (dropWhileEnd, lookup)
22+
import Data.List (dropWhileEnd)
2423
import Data.Maybe (fromMaybe)
2524
import Data.Text (Text)
2625
import Network.DNS.Lookup (lookupSRV, lookupTXT)
@@ -60,7 +59,7 @@ connectTo hostname (PortNumber port) = do
6059
proto <- BSD.getProtocolNumber "tcp"
6160
bracketOnError
6261
(N.socket N.AF_INET N.Stream proto)
63-
(N.close) -- only done if there's an error
62+
N.close -- only done if there's an error
6463
(\sock -> do
6564
he <- BSD.getHostByName hostname
6665
N.connect sock (N.SockAddrInet port (hostAddress he))
@@ -71,7 +70,7 @@ connectTo hostname (PortNumber port) = do
7170
connectTo _ (UnixSocket path) = do
7271
bracketOnError
7372
(N.socket N.AF_UNIX N.Stream 0)
74-
(N.close)
73+
N.close
7574
(\sock -> do
7675
N.connect sock (N.SockAddrUnix path)
7776
N.socketToHandle sock ReadWriteMode
@@ -104,4 +103,4 @@ lookupSeedList hostname = do
104103
Left _ -> pure []
105104
Right srv -> pure $ map (\(_, _, por, tar) ->
106105
let tar' = dropWhileEnd (=='.') (unpack tar)
107-
in Host tar' (PortNumber . fromIntegral $ por)) srv
106+
in Host tar' (PortNumber . fromIntegral $ por)) srv

Database/MongoDB/Internal/Protocol.hs

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
-- This module is not intended for direct use. Use the high-level interface at
55
-- "Database.MongoDB.Query" and "Database.MongoDB.Connection" instead.
66

7-
{-# LANGUAGE RecordWildCards, StandaloneDeriving, OverloadedStrings #-}
8-
{-# LANGUAGE CPP, FlexibleContexts, TupleSections, TypeSynonymInstances #-}
7+
{-# LANGUAGE RecordWildCards, OverloadedStrings #-}
8+
{-# LANGUAGE CPP, FlexibleContexts #-}
99
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, UndecidableInstances #-}
1010
{-# LANGUAGE BangPatterns #-}
1111

@@ -35,7 +35,7 @@ module Database.MongoDB.Internal.Protocol (
3535
#if !MIN_VERSION_base(4,8,0)
3636
import Control.Applicative ((<$>))
3737
#endif
38-
import Control.Monad (forM, replicateM, unless)
38+
import Control.Monad ( forM, replicateM, unless, forever )
3939
import Data.Binary.Get (Get, runGet)
4040
import Data.Binary.Put (Put, runPut)
4141
import Data.Bits (bit, testBit)
@@ -46,7 +46,6 @@ import System.IO.Error (doesNotExistErrorType, mkIOError)
4646
import System.IO.Unsafe (unsafePerformIO)
4747
import Data.Maybe (maybeToList)
4848
import GHC.Conc (ThreadStatus(..), threadStatus)
49-
import Control.Monad (forever)
5049
import Control.Monad.STM (atomically)
5150
import Control.Concurrent (ThreadId, killThread, forkIOWithUnmask)
5251
import Control.Concurrent.STM.TChan (TChan, newTChan, readTChan, writeTChan, isEmptyTChan)
@@ -70,6 +69,7 @@ import Database.MongoDB.Internal.Util (bitOr, byteStringHex)
7069
import Database.MongoDB.Transport (Transport)
7170
import qualified Database.MongoDB.Transport as Tr
7271

72+
7373
#if MIN_VERSION_base(4,6,0)
7474
import Control.Concurrent.MVar.Lifted (MVar, newEmptyMVar, newMVar, withMVar,
7575
putMVar, readMVar, mkWeakMVar, isEmptyMVar)
@@ -83,6 +83,7 @@ mkWeakMVar :: MVar a -> IO () -> IO ()
8383
mkWeakMVar = addMVarFinalizer
8484
#endif
8585

86+
8687
-- * Pipeline
8788

8889
-- | Thread-safe and pipelined connection
@@ -270,6 +271,7 @@ type ResponseTo = RequestId
270271

271272
genRequestId :: (MonadIO m) => m RequestId
272273
-- ^ Generate fresh request id
274+
{-# NOINLINE genRequestId #-}
273275
genRequestId = liftIO $ atomicModifyIORef counter $ \n -> (n + 1, n) where
274276
counter :: IORef RequestId
275277
counter = unsafePerformIO (newIORef 0)

0 commit comments

Comments
 (0)