Reputation: 323
I have a Yesod application with shopping carts which works great. I now want to purge the expired carts in an external app ("app/tasks.hs" in the scaffolding) which will be run with cron. The following code works, but every log message is followed with a blank line. Am I doing something wrong? Side question: how could I convert this to fast-logger? I've read Application.hs in the scaffolding but I didn't manage how to avoid the creation of a foundation...
import Control.Monad.Logger (runStdoutLoggingT, LoggingT)
import Database.Persist.Sqlite (runSqlPool)
import Data.Text (append)
import Import
import qualified Database.Esqueleto as E
runQueries :: UTCTime -> NominalDiffTime -> SqlPersistT (ResourceT (LoggingT IO)) ()
runQueries now expiration = do
$(logInfo) "Delete expired shopping carts."
carts <-
E.select $
E.from $ \(c, u) -> do
E.where_ ( c E.^. CartUpdated E.<. E.val (addUTCTime (- expiration) now)
E.&&. c E.^. CartCustomer E.==. u E.^. UserId
)
return (c, u)
forM_ carts $ \(cart, user) -> do
cartitems <- selectList [ CartItemCart ==. entityKey cart ] []
forM_ cartitems $ \ci -> do
update (cartItemItem $ entityVal ci) [ItemStock +=. (cartItemQuantity $ entityVal ci)]
delete $ entityKey ci
delete $ entityKey cart
$(logInfo) $ "Deleted cart: " `append` (userEmail $ entityVal user)
main :: IO ()
main = do
-- Get the settings from all relevant sources
settings <- loadAppSettingsArgs
-- fall back to compile-time values, set to [] to require values at runtime
[configSettingsYmlValue]
-- allow environment variables to override
useEnv
now <- getCurrentTime
pool <- createPoolConfig (appDatabaseConf settings)
runStdoutLoggingT $ runResourceT $ runSqlPool (runQueries now $ appCartExpiration settings) pool
Upvotes: 1
Views: 128
Reputation: 31345
Good catch, that's actually a bug in monad-logger. I've released version 0.3.10.1 that fixes it.
EDIT Here's an example of using fast-logger with monad-logger:
{-# LANGUAGE OverloadedStrings, TemplateHaskell #-}
import Control.Monad.Logger
import System.Log.FastLogger
import Control.Concurrent (threadDelay)
main :: IO ()
main = do
loggerSet <- newStderrLoggerSet defaultBufSize
let logFunc loc src level str = do
pushLogStr loggerSet (defaultLogStr loc src level str)
flip runLoggingT logFunc $ do
$logInfo "foo"
$logInfo "foo"
$logInfo "foo"
$logInfo "foo"
flushLogStr loggerSet
Upvotes: 3