More aggressive transaction commits & Cleanup

Fixes #198
This commit is contained in:
Gregor Kleen 2018-10-05 12:30:39 +02:00
parent 9040ff4d3d
commit 8dcdcae086
3 changed files with 24 additions and 18 deletions

View File

@ -1326,6 +1326,7 @@ instance YesodMail UniWorX where
mailT ls mail = defMailT ls $ do mailT ls mail = defMailT ls $ do
setMailObjectId setMailObjectId
setDateCurrent setDateCurrent
replaceMailHeader "Auto-Submitted" $ Just "auto-generated"
ret <- mail ret <- mail

View File

@ -28,7 +28,7 @@ import qualified Data.Text.Lazy as LT
import Data.Aeson (fromJSON, toJSON) import Data.Aeson (fromJSON, toJSON)
import qualified Data.Aeson as Aeson import qualified Data.Aeson as Aeson
import Database.Persist.Sql (executeQQ, fromSqlKey) import Database.Persist.Sql (executeQQ, fromSqlKey, transactionSave)
import Data.Monoid (Last(..)) import Data.Monoid (Last(..))
import Control.Monad.Trans.Writer (WriterT(..), execWriterT) import Control.Monad.Trans.Writer (WriterT(..), execWriterT)
@ -78,8 +78,7 @@ handleJobs' = C.mapM_ $ void . handleAny ($logErrorS "Jobs" . tshow) . handleCmd
jLocked :: QueuedJobId -> (QueuedJob -> Handler a) -> Handler a jLocked :: QueuedJobId -> (QueuedJob -> Handler a) -> Handler a
jLocked jId act = do jLocked jId act = do
hasLock <- liftIO $ newTVarIO False hasLock <- liftIO $ newTVarIO False
val <- runDB $ do val <- runDB . setSerializable $ do
setSerializable
j@QueuedJob{..} <- maybe (throwM $ JNonexistant jId) return =<< get jId j@QueuedJob{..} <- maybe (throwM $ JNonexistant jId) return =<< get jId
maybe (return ()) throwM $ JLocked <$> pure jId <*> queuedJobLockInstance <*> queuedJobLockTime maybe (return ()) throwM $ JLocked <$> pure jId <*> queuedJobLockInstance <*> queuedJobLockTime
case fromJSON queuedJobContent :: Aeson.Result Job of case fromJSON queuedJobContent :: Aeson.Result Job of
@ -97,8 +96,7 @@ jLocked jId act = do
act val `finally` whenM (liftIO . atomically $ readTVar hasLock) jUnlock act val `finally` whenM (liftIO . atomically $ readTVar hasLock) jUnlock
where where
jUnlock :: Handler () jUnlock :: Handler ()
jUnlock = runDB $ do jUnlock = runDB . setSerializable $
setSerializable
update jId [ QueuedJobLockInstance =. Nothing update jId [ QueuedJobLockInstance =. Nothing
, QueuedJobLockTime =. Nothing , QueuedJobLockTime =. Nothing
] ]
@ -110,25 +108,28 @@ writeJobCtl cmd = do
queueJob :: Job -> YesodDB UniWorX QueuedJobId queueJob :: Job -> YesodDB UniWorX QueuedJobId
queueJob job = do queueJob job = do
setSerializable jId <- setSerializable $ do
now <- liftIO getCurrentTime now <- liftIO getCurrentTime
self <- getsYesod appInstanceID self <- getsYesod appInstanceID
jId <- insert QueuedJob insert QueuedJob
{ queuedJobContent = toJSON job { queuedJobContent = toJSON job
, queuedJobCreationInstance = self , queuedJobCreationInstance = self
, queuedJobCreationTime = now , queuedJobCreationTime = now
, queuedJobLockInstance = Nothing , queuedJobLockInstance = Nothing
, queuedJobLockTime = Nothing , queuedJobLockTime = Nothing
} }
writeJobCtl $ JobCtlPerform jId -- FIXME: Should do fancy load balancing across instances (or something) writeJobCtl $ JobCtlPerform jId -- FIXME: Should do fancy load balancing across instances (or something)
return jId return jId
setSerializable :: DB () setSerializable :: DB a -> DB a
setSerializable = [executeQQ|SET TRANSACTION ISOLATION LEVEL SERIALIZABLE|] setSerializable act = do
transactionSave
[executeQQ|SET TRANSACTION ISOLATION LEVEL SERIALIZABLE|]
act <* transactionSave
performJob :: Job -> WriterT (Last Bool) (HandlerT UniWorX IO) () performJob :: Job -> WriterT (Last Bool) (HandlerT UniWorX IO) ()
performJob JobSendNotification{ jNotification = NotificationSubmissionRated{..}, .. } = do performJob JobSendNotification{ jNotification = NotificationSubmissionRated{..}, .. } = do
$logDebugS "Jobs" "NotificationSubmissionRated"
fail "NotificationSubmissionRated not implemented yet" -- TODO fail "NotificationSubmissionRated not implemented yet" -- TODO
performJob JobSendTestEmail{..} = do performJob JobSendTestEmail{..} = do
$logInfoS "Jobs" $ "Sending test-email to " <> jEmail $logInfoS "Jobs" $ "Sending test-email to " <> jEmail

View File

@ -190,12 +190,14 @@ class YesodMail site where
mailT :: ( MonadHandler m mailT :: ( MonadHandler m
, HandlerSite m ~ site , HandlerSite m ~ site
, MonadBaseControl IO m , MonadBaseControl IO m
, MonadLogger m
) => MailLanguages -> MailT m a -> m a ) => MailLanguages -> MailT m a -> m a
mailT = defMailT mailT = defMailT
defMailT :: ( MonadHandler m defMailT :: ( MonadHandler m
, YesodMail (HandlerSite m) , YesodMail (HandlerSite m)
, MonadBaseControl IO m , MonadBaseControl IO m
, MonadLogger m
) => MailLanguages -- ^ Languages in priority order ) => MailLanguages -- ^ Languages in priority order
-> MailT m a -> MailT m a
-> m a -> m a
@ -203,6 +205,8 @@ defMailT ls (MailT mail) = do
fromAddress <- defaultFromAddress fromAddress <- defaultFromAddress
(ret, mail, smtpData) <- runRWST mail ls (emptyMail fromAddress) (ret, mail, smtpData) <- runRWST mail ls (emptyMail fromAddress)
mail' <- liftIO $ LBS.toStrict <$> renderMail' mail mail' <- liftIO $ LBS.toStrict <$> renderMail' mail
$logDebugS "Mail" $ "Rendered mail:\n" <> decodeUtf8 mail'
$logInfoS "Mail" $ "Submitting email: " <> tshow smtpData
ret <$ case smtpData of ret <$ case smtpData of
MailSmtpData{ smtpEnvelopeFrom = Last Nothing } -> throwM MailNoSenderSpecified MailSmtpData{ smtpEnvelopeFrom = Last Nothing } -> throwM MailNoSenderSpecified
MailSmtpData{ smtpRecipients } MailSmtpData{ smtpRecipients }