packages feed

project-m36-1.2.0: src/bin/benchmark/Server.hs

{-# LANGUAGE DerivingVia, DeriveGeneric #-}
import ProjectM36.Tupleable
import ProjectM36.Client

import Criterion.Main
import Codec.Winery
import Data.Text (Text)
import Data.Proxy
import GHC.Generics
import Control.Monad
import System.Random

handleIOError :: Show e => IO (Either e a) -> IO a
handleIOError m = do
  v <- m
  handleError v

handleError :: Show e => Either e a -> IO a
handleError eErr = case eErr of
    Left err -> print err >> error "Died due to errors."
    Right v -> pure v

--test local connection speeds of inserts, updates, and deletes to look for space leaks, etc.
main :: IO ()
main = do
  rando <- initStdGen
  conn <- handleIOError $ connectProjectM36 (InProcessConnectionInfo NoPersistence emptyNotificationCallback [] basicDatabaseContext rando adminRoleName)
  sess <- handleIOError $ createSessionAtHead conn "master"
  _ <- handleIOError $ executeDatabaseContextExpr sess conn (toDefineExpr (Proxy :: Proxy User) "user")

  let count = 100
  insertUsers sess conn count
  defaultMain [
    bgroup "inserts" [
        bench "insert" $ nfIO $ insertUsers sess conn count]
    {-,bgroup "updates" [
        bench "update" $ nfIO $ updateUsers sess conn count
        ]-}
    ,bgroup "delete" [
        bench "delete" $ nfIO $ deleteUsers sess conn count
        ]
    ]


insertUsers :: SessionId -> Connection -> Int -> IO ()
insertUsers sess conn count = 
  forM_ [1 .. count] $ \newId -> do
    let newUser = User { userId = newId
                       , userFirstName = "Steve"
                       , userLastName = "Stevens"
                       , userEmail = "bench@bench.com"
                       }
    newUserExpr <- handleError (toInsertExpr [newUser] "user")
    handleIOError $ executeDatabaseContextExpr sess conn newUserExpr

{-
updateUsers :: SessionId -> Connection -> Int -> IO ()
updateUsers sess conn count =
  forM_ [1 .. count] $ \uid -> do
    let changeUser = User { userId = uid
                          , userFirstName = "Steve"
                          , userLastName = "Stevens III"
                          , userEmail = "bench@bench.com"
                          }
        updateExpr = toUpdateExpr "user" ["userId"] changeUser
    updateUserExpr <- handleError updateExpr
    handleIOError $ executeDatabaseContextExpr sess conn updateUserExpr
-}
deleteUsers :: SessionId -> Connection -> Int -> IO ()
deleteUsers sess conn count =
  forM_ [1 .. count] $ \uid -> do
    let delUser = User { userId = uid
                       , userFirstName = "Steve"
                       , userLastName = "Stevens III"
                       , userEmail = "bench@bench.com"
                       }
    delUserExpr <- handleError (toDeleteExpr "user" ["userId"] delUser)
    handleIOError $ executeDatabaseContextExpr sess conn delUserExpr

data User = User
          { userId :: Int
          , userFirstName :: Text
          , userLastName :: Text
          , userEmail :: Text
          }
          deriving Generic
          deriving Serialise via WineryRecord User

instance Tupleable User