Merge pull request #293 from fpco/bench

Benchmark stackage queries
This commit is contained in:
Michael Snoyman 2020-07-24 08:01:22 +03:00 committed by GitHub
commit c308e89a16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 186 additions and 42 deletions

View File

@ -2,7 +2,7 @@ name: Runtime image
on: on:
push: push:
branches: [master] branches: [master, bench]
jobs: jobs:
push: push:

117
bench/main.hs Normal file
View File

@ -0,0 +1,117 @@
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
import Control.Monad.Logger (runNoLoggingT, runStdoutLoggingT)
import Data.Pool (destroyAllResources)
import Database.Persist.Postgresql (PostgresConf(..), createPostgresqlPool)
import Database.Persist.Sql (ConnectionPool, SqlBackend, runSqlPool)
import Gauge
import Pantry.Internal.Stackage (PackageNameP(..))
import RIO
import Settings (getAppSettings, AppSettings(..), configSettingsYmlValue)
import Stackage.Database.Query
import Stackage.Database.Schema (withStackageDatabase, runDatabase)
import Stackage.Database.Types (LatestInfo, SnapName(..), SnapshotPackageInfo(..))
import Yesod.Default.Config2
main :: IO ()
main = do
appSettings <- getAppSettings
let pgConf =
PostgresConf
{ pgPoolSize = appPostgresPoolsize appSettings
, pgConnStr = encodeUtf8 $ appPostgresString appSettings
}
let snapName = SNLts 16 4
mSnapInfo <-
runSimpleApp $
withStackageDatabase
True
pgConf
(\db -> runDatabase db $ getSnapshotPackageInfoQuery snapName (PackageNameP "yesod"))
let snapInfo = fromMaybe (error "snapInfo not retrieved") mSnapInfo
defaultMain [benchs snapInfo]
runBenchApp :: ConnectionPool -> ReaderT SqlBackend (RIO SimpleApp) a -> IO a
runBenchApp pool m = runSimpleApp $ runSqlPool m pool
createBenchPool :: IO ConnectionPool
createBenchPool = do
baSettings <- loadYamlSettingsArgs [configSettingsYmlValue] useEnv
pool <-
runNoLoggingT $
createPostgresqlPool
(encodeUtf8 $ appPostgresString baSettings)
(appPostgresPoolsize baSettings)
pure pool
releasePool :: ConnectionPool -> IO ()
releasePool = destroyAllResources
-- TODO: Upstream fix ? Or add new function to gauge (although it
-- seems it might be a breaking change there) ?
instance NFData ConnectionPool where
rnf _ = ()
getLatestsBench :: Benchmark
getLatestsBench =
bench "getLatests" $
perBatchEnvWithCleanup
(\runs -> createBenchPool)
(\_ pool -> releasePool pool)
(\pool -> runBenchApp pool (void $ getLatests $ PackageNameP "yesod"))
getDeprecatedBench :: Benchmark
getDeprecatedBench =
bench "getDeprecated" $
perBatchEnvWithCleanup
(\runs -> createBenchPool)
(\_ pool -> releasePool pool)
(\pool -> runBenchApp pool (void $ getDeprecatedQuery $ PackageNameP "yesod"))
getSnapshotPackageLatestVersionBench :: Benchmark
getSnapshotPackageLatestVersionBench =
bench "getSnapshotPackageLatestVersion" $
perBatchEnvWithCleanup
(\runs -> createBenchPool)
(\_ pool -> releasePool pool)
(\pool ->
runBenchApp pool (void $ getSnapshotPackageLatestVersionQuery $ PackageNameP "yesod"))
getSnapshotPackagePageInfoBench :: SnapshotPackageInfo -> Benchmark
getSnapshotPackagePageInfoBench snapshotInfo =
bench "getSnapshotPackagePageInfo" $
perBatchEnvWithCleanup
(\runs -> createBenchPool)
(\_ pool -> releasePool pool)
(\pool -> runBenchApp pool (void $ getSnapshotPackagePageInfoQuery snapshotInfo 40))
getPackageInfoBench :: SnapshotPackageInfo -> Benchmark
getPackageInfoBench snapInfo =
bench "getPackageInfo" $
perBatchEnvWithCleanup
(\runs -> createBenchPool)
(\_ pool -> releasePool pool)
(\pool -> runBenchApp pool (void $ getPackageInfoQuery (Right snapInfo)))
getHackageLatestVersionBench :: Benchmark
getHackageLatestVersionBench =
bench "getHackageLatestVersion" $
perBatchEnvWithCleanup
(\runs -> createBenchPool)
(\_ pool -> releasePool pool)
(\pool -> runBenchApp pool (void $ getHackageLatestVersion $ PackageNameP "yesod"))
benchs :: SnapshotPackageInfo -> Benchmark
benchs snap =
bgroup
"SQL Query Benchmark"
[ getLatestsBench
, getDeprecatedBench
, getHackageLatestVersionBench
, getPackageInfoBench snap
, getSnapshotPackagePageInfoBench snap
, getSnapshotPackageLatestVersionBench
]

View File

@ -145,3 +145,16 @@ executables:
buildable: false buildable: false
- condition: flag(dev) - condition: flag(dev)
cpp-options: -DDEVELOPMENT cpp-options: -DDEVELOPMENT
benchmarks:
stackage-bench:
main: main.hs
source-dirs: bench
dependencies:
- stackage-server
- gauge
- deepseq
- path-io
- casa-client
ghc-options:
- -O2

View File

@ -86,14 +86,16 @@ packagePage mspi pname =
handlePackage :: Either HackageCabalInfo SnapshotPackageInfo -> Handler Html handlePackage :: Either HackageCabalInfo SnapshotPackageInfo -> Handler Html
handlePackage epi = do handlePackage epi = do
(isDeprecated, inFavourOf) <- getDeprecated pname (isDeprecated, inFavourOf, snapInfo, PackageInfo{..}) <- run $ do
(msppi, mhciLatest) <- (isDeprecated, inFavourOf) <- getDeprecatedQuery pname
case epi of snapInfo <- case epi of
Right spi -> do Right spi -> Right <$> getSnapshotPackagePageInfoQuery spi maxDisplayedDeps
sppi <- getSnapshotPackagePageInfo spi maxDisplayedDeps Left hci -> pure $ Left hci
return (Just sppi, sppiLatestHackageCabalInfo sppi) pinfo <- getPackageInfoQuery epi
Left hci -> pure (Nothing, Just hci) pure (isDeprecated, inFavourOf, snapInfo, pinfo)
PackageInfo {..} <- getPackageInfo epi (msppi, mhciLatest) <- case snapInfo of
Left hci -> pure (Nothing, Just hci)
Right sppi -> pure (Just sppi, sppiLatestHackageCabalInfo sppi)
let authors = enumerate piAuthors let authors = enumerate piAuthors
maintainers = maintainers =
let ms = enumerate piMaintainers let ms = enumerate piMaintainers

View File

@ -33,9 +33,13 @@ module Stackage.Database.Query
, getLatests , getLatests
, getHackageLatestVersion , getHackageLatestVersion
, getSnapshotPackageInfo , getSnapshotPackageInfo
, getSnapshotPackageInfoQuery
, getSnapshotPackageLatestVersion , getSnapshotPackageLatestVersion
, getSnapshotPackageLatestVersionQuery
, getSnapshotPackagePageInfo , getSnapshotPackagePageInfo
, getSnapshotPackagePageInfoQuery
, getPackageInfo , getPackageInfo
, getPackageInfoQuery
, getSnapshotsForPackage , getSnapshotsForPackage
-- ** Dependencies -- ** Dependencies
@ -46,6 +50,7 @@ module Stackage.Database.Query
-- ** Deprecations -- ** Deprecations
, getDeprecated , getDeprecated
, getDeprecatedQuery
, setDeprecations , setDeprecations
-- * Needed for Cron Job -- * Needed for Cron Job
@ -474,17 +479,18 @@ getHackageLatestVersion pname =
getSnapshotPackageInfo :: getSnapshotPackageInfo ::
GetStackageDatabase env m => SnapName -> PackageNameP -> m (Maybe SnapshotPackageInfo) GetStackageDatabase env m => SnapName -> PackageNameP -> m (Maybe SnapshotPackageInfo)
getSnapshotPackageInfo snapName pname = getSnapshotPackageInfo snapName pname = run $ getSnapshotPackageInfoQuery snapName pname
getSnapshotPackageInfoQuery ::
SnapName -> PackageNameP -> ReaderT SqlBackend (RIO env) (Maybe SnapshotPackageInfo)
getSnapshotPackageInfoQuery snapName pname =
fmap snd . listToMaybe <$> fmap snd . listToMaybe <$>
run (snapshotPackageInfoQuery $ \_sp s pn _v spiQ -> do (snapshotPackageInfoQuery $ \_sp s pn _v spiQ -> do
where_ ((s ^. SnapshotName ==. val snapName) &&. (pn ^. PackageNameName ==. val pname)) where_ ((s ^. SnapshotName ==. val snapName) &&. (pn ^. PackageNameName ==. val pname))
pure ((), spiQ)) pure ((), spiQ))
getSnapshotPackagePageInfoQuery :: SnapshotPackageInfo -> Int -> ReaderT SqlBackend (RIO env) SnapshotPackagePageInfo
getSnapshotPackagePageInfo :: getSnapshotPackagePageInfoQuery spi maxDisplayedDeps = do
GetStackageDatabase env m => SnapshotPackageInfo -> Int -> m SnapshotPackagePageInfo
getSnapshotPackagePageInfo spi maxDisplayedDeps =
run $ do
mhciLatest <- getHackageLatestVersion $ spiPackageName spi mhciLatest <- getHackageLatestVersion $ spiPackageName spi
-- TODO: check for `spiOrigin spi` once other than `Hackage` are implemented -- TODO: check for `spiOrigin spi` once other than `Hackage` are implemented
forwardDepsCount <- getForwardDepsCount spi forwardDepsCount <- getForwardDepsCount spi
@ -519,6 +525,10 @@ getSnapshotPackagePageInfo spi maxDisplayedDeps =
where where
VersionRev curVer mcurRev = spiVersionRev spi VersionRev curVer mcurRev = spiVersionRev spi
getSnapshotPackagePageInfo ::
GetStackageDatabase env m => SnapshotPackageInfo -> Int -> m SnapshotPackagePageInfo
getSnapshotPackagePageInfo spi maxDisplayedDeps = run $ getSnapshotPackagePageInfoQuery spi maxDisplayedDeps
type SqlExprSPI type SqlExprSPI
= ( SqlExpr (Value SnapshotPackageId) = ( SqlExpr (Value SnapshotPackageId)
, SqlExpr (Value SnapshotId) , SqlExpr (Value SnapshotId)
@ -576,21 +586,21 @@ snapshotPackageInfoQuery customize =
} }
getSnapshotPackageLatestVersionQuery ::
PackageNameP -> ReaderT SqlBackend (RIO env) (Maybe SnapshotPackageInfo)
getSnapshotPackageLatestVersionQuery pname =
fmap snd . listToMaybe <$>
(snapshotPackageInfoQuery $ \_sp s pn v spiQ -> do
where_ (pn ^. PackageNameName ==. val pname)
orderBy [desc (versionArray v), desc (s ^. SnapshotCreated)]
limit 1
pure ((), spiQ))
getSnapshotPackageLatestVersion :: getSnapshotPackageLatestVersion ::
GetStackageDatabase env m GetStackageDatabase env m
=> PackageNameP => PackageNameP
-> m (Maybe SnapshotPackageInfo) -> m (Maybe SnapshotPackageInfo)
getSnapshotPackageLatestVersion pname = getSnapshotPackageLatestVersion pname = run (getSnapshotPackageLatestVersionQuery pname)
fmap snd . listToMaybe <$>
run (snapshotPackageInfoQuery $ \_sp s pn v spiQ -> do
where_ (pn ^. PackageNameName ==. val pname)
orderBy
[ desc (versionArray v)
, desc (s ^. SnapshotCreated)
]
limit 1
pure ((), spiQ))
-- | A helper function that expects at most one element to be returned by a `select` and applies a -- | A helper function that expects at most one element to be returned by a `select` and applies a
-- function to the returned result -- function to the returned result
@ -628,15 +638,11 @@ getSnapshotsForPackage pname mlimit =
pure (s ^. SnapshotCompiler, spiQ)) pure (s ^. SnapshotCompiler, spiQ))
getPackageInfoQuery :: Either HackageCabalInfo SnapshotPackageInfo -> ReaderT SqlBackend (RIO env) PackageInfo
getPackageInfo :: getPackageInfoQuery (Left hci) = do
GetStackageDatabase env m => Either HackageCabalInfo SnapshotPackageInfo -> m PackageInfo cabalBlob <- loadBlobById (hciCabalBlobId hci)
getPackageInfo (Left hci) = pure $ toPackageInfo (parseCabalBlob cabalBlob) Nothing Nothing
run $ do getPackageInfoQuery (Right spi) = do
cabalBlob <- loadBlobById (hciCabalBlobId hci)
pure $ toPackageInfo (parseCabalBlob cabalBlob) Nothing Nothing
getPackageInfo (Right spi) =
run $
case spiCabalBlobId spi of case spiCabalBlobId spi of
Just cabalBlobId -> do Just cabalBlobId -> do
gpd <- parseCabalBlob <$> loadBlobById cabalBlobId gpd <- parseCabalBlob <$> loadBlobById cabalBlobId
@ -652,6 +658,10 @@ getPackageInfo (Right spi) =
toContentFile :: (ByteString -> Bool -> a) -> (SafeFilePath, ByteString) -> a toContentFile :: (ByteString -> Bool -> a) -> (SafeFilePath, ByteString) -> a
toContentFile con (path, bs) = con bs (isMarkdownFilePath path) toContentFile con (path, bs) = con bs (isMarkdownFilePath path)
getPackageInfo ::
GetStackageDatabase env m => Either HackageCabalInfo SnapshotPackageInfo -> m PackageInfo
getPackageInfo args = run $ getPackageInfoQuery args
getFileByTreeEntryId :: getFileByTreeEntryId ::
TreeEntryId TreeEntryId
-> ReaderT SqlBackend (RIO env) (Maybe (SafeFilePath, ByteString)) -> ReaderT SqlBackend (RIO env) (Maybe (SafeFilePath, ByteString))
@ -753,10 +763,8 @@ getReverseDeps spi mlimit =
----- Deprecated ----- Deprecated
-- | See if a package is deprecated on hackage and in favour of which packages. getDeprecatedQuery :: PackageNameP -> ReaderT SqlBackend (RIO env) (Bool, [PackageNameP])
getDeprecated :: GetStackageDatabase env m => PackageNameP -> m (Bool, [PackageNameP]) getDeprecatedQuery pname =
getDeprecated pname =
run $
lookupPackageNameId pname >>= \case lookupPackageNameId pname >>= \case
Just pnid -> Just pnid ->
P.getBy (UniqueDeprecated pnid) >>= \case P.getBy (UniqueDeprecated pnid) >>= \case
@ -768,6 +776,10 @@ getDeprecated pname =
where where
defRes = (False, []) defRes = (False, [])
-- | See if a package is deprecated on hackage and in favour of which packages.
getDeprecated :: GetStackageDatabase env m => PackageNameP -> m (Bool, [PackageNameP])
getDeprecated pname = run $ getDeprecatedQuery pname
-------------------------- --------------------------