13
13
{-# LANGUAGE FlexibleContexts #-}
14
14
{-# OPTIONS_GHC -fno-warn-orphans #-}
15
15
module Main (main , resourcesApp , Widget , WorldId ) where
16
+ import Blaze.ByteString.Builder
17
+ import Control.Concurrent (runInUnboundThread )
16
18
import Control.Monad (replicateM )
17
19
import Control.Monad.Logger (runNoLoggingT )
18
20
import Control.Monad.Primitive (PrimState )
19
21
import Control.Monad.Reader (ReaderT )
20
- import Data.Conduit.Pool (Pool )
22
+ import Control.Monad.Trans.Resource (InternalState )
23
+ import Data.Aeson (encode )
24
+ import qualified Data.ByteString.Lazy as L
25
+ import Data.Conduit.Pool (Pool , createPool )
21
26
import Data.Int (Int64 )
27
+ import Data.Pool (withResource )
22
28
import Data.Text (Text )
23
29
import Database.MongoDB (Field ((:=) ), (=:) )
24
30
import qualified Database.MongoDB as Mongo
25
- import qualified Database.Persist.MongoDB as Mongo
26
31
import qualified Database.Persist.MySQL as My
27
32
import Network (PortID (PortNumber ))
33
+ import Network.HTTP.Types
34
+ import Network.Wai
28
35
import qualified Network.Wai.Handler.Warp as Warp
29
36
import System.Environment (getArgs )
30
37
import qualified System.Random.MWC as R
31
38
import Yesod hiding (Field )
39
+ import Data.IORef (newIORef )
40
+ import System.IO.Unsafe (unsafePerformIO )
32
41
33
42
mkPersist sqlSettings { mpsGeneric = True } [persistLowerCase |
34
43
World sql=World
35
44
randomNumber Int sql=randomNumber
36
- #ifdef MONGODB
37
- id Int64
38
- UniqueId
39
- #endif
40
45
|]
41
46
42
47
data App = App
43
48
{ appGen :: ! (R. Gen (PrimState IO ))
44
49
, mySqlPool :: ! (Pool My. SqlBackend )
45
- , mongoDBPool :: ! (Pool Mongo. Connection )
50
+ , mongoDBPool :: ! (Pool Mongo. Pipe )
46
51
}
47
52
48
53
-- | Not actually using the non-raw mongoDB.
@@ -53,15 +58,14 @@ mkYesod "App" [parseRoutes|
53
58
/db DbR GET
54
59
/dbs/#Int DbsR GET
55
60
56
- #ifdef MONGODB
57
- /mongo/db MongoDbR GET
58
- /mongo/dbs/#Int MongoDbsR GET
59
- #endif
60
-
61
61
/mongo/raw/db MongoRawDbR GET
62
62
/mongo/raw/dbs/#Int MongoRawDbsR GET
63
63
|]
64
64
65
+ fakeInternalState :: InternalState
66
+ fakeInternalState = unsafePerformIO $ newIORef $ error " fakeInternalState forced"
67
+ {-# NOINLINE fakeInternalState #-}
68
+
65
69
instance Yesod App where
66
70
makeSessionBackend _ = return Nothing
67
71
{-# INLINE makeSessionBackend #-}
@@ -71,20 +75,25 @@ instance Yesod App where
71
75
{-# INLINE yesodMiddleware #-}
72
76
cleanPath _ = Right
73
77
{-# INLINE cleanPath #-}
74
-
75
- getJsonR :: Handler TypedContent
76
- getJsonR = return $ TypedContent typeJson
77
- $ toContent $ object [" message" .= (" Hello, World!" :: Text )]
78
+ yesodWithInternalState _ _ = ($ fakeInternalState)
79
+ {-# INLINE yesodWithInternalState #-}
80
+ maximumContentLength _ _ = Nothing
81
+ {-# INLINE maximumContentLength #-}
82
+
83
+ getJsonR :: Handler ()
84
+ getJsonR = sendWaiResponse
85
+ $ responseBuilder
86
+ status200
87
+ [(" Content-Type" , typeJson)]
88
+ $ copyByteString
89
+ $ L. toStrict
90
+ $ encode
91
+ $ object [" message" .= (" Hello, World!" :: Text )]
78
92
79
93
80
94
getDbR :: Handler Value
81
95
getDbR = getDb (intQuery runMySQL My. toSqlKey)
82
96
83
- #ifdef MONGODB
84
- getMongoDbR :: Handler Value
85
- getMongoDbR = getDb (intQuery runMongoDB (getBy . UniqueId ))
86
- #endif
87
-
88
97
getMongoRawDbR :: Handler Value
89
98
getMongoRawDbR = getDb rawMongoIntQuery
90
99
@@ -93,11 +102,6 @@ getDbsR cnt = do
93
102
App {.. } <- getYesod
94
103
multiRandomHandler (intQuery runMySQL My. toSqlKey) cnt
95
104
96
- #ifdef MONGODB
97
- getMongoDbsR :: Int -> Handler Value
98
- getMongoDbsR cnt = multiRandomHandler (intQuery runMongoDB (getBy . UniqueId )) cnt
99
- #endif
100
-
101
105
getMongoRawDbsR :: Int -> Handler Value
102
106
getMongoRawDbsR cnt = multiRandomHandler rawMongoIntQuery cnt
103
107
@@ -109,13 +113,21 @@ getDb :: (Int64 -> Handler Value) -> Handler Value
109
113
getDb query = do
110
114
app <- getYesod
111
115
i <- liftIO (randomNumber (appGen app))
112
- query i
116
+ value <- query i
117
+ sendWaiResponse
118
+ $ responseBuilder
119
+ status200
120
+ [(" Content-Type" , typeJson)]
121
+ $ copyByteString
122
+ $ L. toStrict
123
+ $ encode value
113
124
114
125
115
126
runMongoDB :: Mongo. Action Handler b -> Handler b
116
127
runMongoDB f = do
117
128
App {.. } <- getYesod
118
- Mongo. runMongoDBPoolDef f mongoDBPool
129
+ withResource mongoDBPool $ \ pipe ->
130
+ Mongo. access pipe Mongo. ReadStaleOk " hello_world" f
119
131
120
132
runMySQL :: My. SqlPersistT Handler b -> Handler b
121
133
runMySQL f = do
@@ -167,26 +179,27 @@ instance ToJSON Mongo.Value where
167
179
168
180
main :: IO ()
169
181
main = R. withSystemRandom $ \ gen -> do
170
- [_cores , host] <- getArgs
182
+ [cores , host] <- getArgs
171
183
myPool <- runNoLoggingT $ My. createMySQLPool My. defaultConnectInfo
172
184
{ My. connectUser = " benchmarkdbuser"
173
185
, My. connectPassword = " benchmarkdbpass"
174
186
, My. connectDatabase = " hello_world"
175
187
, My. connectHost = host
176
188
} 1000
177
189
178
- mongoPool <- Mongo. createMongoDBPool " hello_world" host (PortNumber 27017 )
179
- (Just (Mongo. MongoAuth " benchmarkdbuser" " benchmarkdbpass" ))
180
- 1 -- what is the optimal stripe count? 1 is said to be a good default
181
- 1000
182
- 3 -- 3 second timeout
190
+ mongoPool <- createPool
191
+ (Mongo. connect $ Mongo. Host host $ PortNumber 27017 )
192
+ Mongo. close
193
+ (read cores) -- what is the optimal stripe count? 1 is said to be a good default
194
+ 3 -- 3 second timeout
195
+ 1000
183
196
184
197
app <- toWaiAppPlain App
185
198
{ appGen = gen
186
199
, mySqlPool = myPool
187
200
, mongoDBPool = mongoPool
188
201
}
189
- Warp. runSettings
202
+ runInUnboundThread $ Warp. runSettings
190
203
( Warp. setPort 8000
191
204
$ Warp. setHost " *"
192
205
$ Warp. setOnException (\ _ _ -> return () )
0 commit comments