2012-10-29 04:15:43 +00:00
|
|
|
{- git-annex assistant monad
|
|
|
|
-
|
|
|
|
- Copyright 2012 Joey Hess <joey@kitenet.net>
|
|
|
|
-
|
|
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
2012-11-02 16:59:31 +00:00
|
|
|
{-# LANGUAGE PackageImports, GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}
|
2012-10-29 04:15:43 +00:00
|
|
|
|
|
|
|
module Assistant.Monad (
|
|
|
|
Assistant,
|
|
|
|
AssistantData(..),
|
|
|
|
newAssistantData,
|
|
|
|
runAssistant,
|
|
|
|
getAssistant,
|
2013-03-16 04:12:28 +00:00
|
|
|
LiftAnnex,
|
2012-10-29 06:21:04 +00:00
|
|
|
liftAnnex,
|
|
|
|
(<~>),
|
|
|
|
(<<~),
|
|
|
|
asIO,
|
2012-10-30 21:14:26 +00:00
|
|
|
asIO1,
|
2012-10-29 06:21:04 +00:00
|
|
|
asIO2,
|
2013-01-26 03:14:32 +00:00
|
|
|
ThreadName,
|
|
|
|
debug,
|
|
|
|
notice
|
2012-10-29 04:15:43 +00:00
|
|
|
) where
|
|
|
|
|
|
|
|
import "mtl" Control.Monad.Reader
|
|
|
|
import Control.Monad.Base (liftBase, MonadBase)
|
2013-01-26 03:14:32 +00:00
|
|
|
import System.Log.Logger
|
2012-10-29 04:15:43 +00:00
|
|
|
|
|
|
|
import Common.Annex
|
2012-10-29 23:07:10 +00:00
|
|
|
import Assistant.Types.ThreadedMonad
|
2012-10-30 18:11:14 +00:00
|
|
|
import Assistant.Types.DaemonStatus
|
2012-10-29 23:14:30 +00:00
|
|
|
import Assistant.Types.ScanRemotes
|
2012-10-30 18:34:48 +00:00
|
|
|
import Assistant.Types.TransferQueue
|
|
|
|
import Assistant.Types.TransferSlots
|
2013-03-19 22:46:29 +00:00
|
|
|
import Assistant.Types.TransferrerPool
|
2012-10-29 21:52:43 +00:00
|
|
|
import Assistant.Types.Pushes
|
2012-10-29 23:20:54 +00:00
|
|
|
import Assistant.Types.BranchChange
|
2012-10-29 23:35:18 +00:00
|
|
|
import Assistant.Types.Commits
|
2012-10-29 23:30:23 +00:00
|
|
|
import Assistant.Types.Changes
|
2012-11-02 16:59:31 +00:00
|
|
|
import Assistant.Types.Buddies
|
2012-11-03 18:16:17 +00:00
|
|
|
import Assistant.Types.NetMessager
|
2013-01-26 06:09:33 +00:00
|
|
|
import Assistant.Types.ThreadName
|
2013-01-26 03:14:32 +00:00
|
|
|
|
2012-10-29 04:15:43 +00:00
|
|
|
newtype Assistant a = Assistant { mkAssistant :: ReaderT AssistantData IO a }
|
|
|
|
deriving (
|
|
|
|
Monad,
|
|
|
|
MonadIO,
|
|
|
|
MonadReader AssistantData,
|
|
|
|
Functor,
|
|
|
|
Applicative
|
|
|
|
)
|
|
|
|
|
|
|
|
instance MonadBase IO Assistant where
|
|
|
|
liftBase = Assistant . liftBase
|
|
|
|
|
|
|
|
data AssistantData = AssistantData
|
2013-01-26 06:09:33 +00:00
|
|
|
{ threadName :: ThreadName
|
2012-10-29 06:21:04 +00:00
|
|
|
, threadState :: ThreadState
|
|
|
|
, daemonStatusHandle :: DaemonStatusHandle
|
2012-10-29 04:15:43 +00:00
|
|
|
, scanRemoteMap :: ScanRemoteMap
|
|
|
|
, transferQueue :: TransferQueue
|
|
|
|
, transferSlots :: TransferSlots
|
2013-03-19 22:46:29 +00:00
|
|
|
, transferrerPool :: TransferrerPool
|
2012-10-29 04:15:43 +00:00
|
|
|
, failedPushMap :: FailedPushMap
|
|
|
|
, commitChan :: CommitChan
|
|
|
|
, changeChan :: ChangeChan
|
|
|
|
, branchChangeHandle :: BranchChangeHandle
|
2012-11-02 16:59:31 +00:00
|
|
|
, buddyList :: BuddyList
|
2012-11-08 18:06:43 +00:00
|
|
|
, netMessager :: NetMessager
|
2012-10-29 04:15:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
newAssistantData :: ThreadState -> DaemonStatusHandle -> IO AssistantData
|
|
|
|
newAssistantData st dstatus = AssistantData
|
2013-01-26 06:09:33 +00:00
|
|
|
<$> pure (ThreadName "main")
|
2012-10-29 06:21:04 +00:00
|
|
|
<*> pure st
|
2012-10-29 04:15:43 +00:00
|
|
|
<*> pure dstatus
|
|
|
|
<*> newScanRemoteMap
|
|
|
|
<*> newTransferQueue
|
|
|
|
<*> newTransferSlots
|
2013-03-19 22:46:29 +00:00
|
|
|
<*> newTransferrerPool
|
2012-10-29 04:15:43 +00:00
|
|
|
<*> newFailedPushMap
|
|
|
|
<*> newCommitChan
|
|
|
|
<*> newChangeChan
|
|
|
|
<*> newBranchChangeHandle
|
2012-11-02 16:59:31 +00:00
|
|
|
<*> newBuddyList
|
2012-11-08 18:06:43 +00:00
|
|
|
<*> newNetMessager
|
2012-10-29 04:15:43 +00:00
|
|
|
|
2012-11-05 23:39:08 +00:00
|
|
|
runAssistant :: AssistantData -> Assistant a -> IO a
|
|
|
|
runAssistant d a = runReaderT (mkAssistant a) d
|
2012-10-29 04:15:43 +00:00
|
|
|
|
|
|
|
getAssistant :: (AssistantData -> a) -> Assistant a
|
|
|
|
getAssistant = reader
|
|
|
|
|
2013-03-16 04:12:28 +00:00
|
|
|
{- Using a type class for lifting into the annex monad allows
|
|
|
|
- easily lifting to it from multiple different monads. -}
|
|
|
|
class LiftAnnex m where
|
|
|
|
liftAnnex :: Annex a -> m a
|
|
|
|
|
2012-10-29 04:15:43 +00:00
|
|
|
{- Runs an action in the git-annex monad. Note that the same monad state
|
|
|
|
- is shared amoung all assistant threads, so only one of these can run at
|
|
|
|
- a time. Therefore, long-duration actions should be avoided. -}
|
2013-03-16 04:12:28 +00:00
|
|
|
instance LiftAnnex Assistant where
|
|
|
|
liftAnnex a = do
|
|
|
|
st <- reader threadState
|
|
|
|
liftIO $ runThreadState st a
|
2012-10-29 06:21:04 +00:00
|
|
|
|
|
|
|
{- Runs an IO action, passing it an IO action that runs an Assistant action. -}
|
|
|
|
(<~>) :: (IO a -> IO b) -> Assistant a -> Assistant b
|
|
|
|
io <~> a = do
|
|
|
|
d <- reader id
|
2012-11-05 23:39:08 +00:00
|
|
|
liftIO $ io $ runAssistant d a
|
2012-10-29 06:21:04 +00:00
|
|
|
|
|
|
|
{- Creates an IO action that will run an Assistant action when run. -}
|
2012-10-30 21:14:26 +00:00
|
|
|
asIO :: Assistant a -> Assistant (IO a)
|
2012-10-29 06:21:04 +00:00
|
|
|
asIO a = do
|
2012-10-30 21:14:26 +00:00
|
|
|
d <- reader id
|
2012-11-05 23:39:08 +00:00
|
|
|
return $ runAssistant d a
|
2012-10-30 21:14:26 +00:00
|
|
|
|
|
|
|
asIO1 :: (a -> Assistant b) -> Assistant (a -> IO b)
|
|
|
|
asIO1 a = do
|
2012-10-29 06:21:04 +00:00
|
|
|
d <- reader id
|
2012-11-05 23:39:08 +00:00
|
|
|
return $ \v -> runAssistant d $ a v
|
2012-10-29 06:21:04 +00:00
|
|
|
|
|
|
|
asIO2 :: (a -> b -> Assistant c) -> Assistant (a -> b -> IO c)
|
|
|
|
asIO2 a = do
|
|
|
|
d <- reader id
|
2012-11-05 23:39:08 +00:00
|
|
|
return $ \v1 v2 -> runAssistant d (a v1 v2)
|
2012-10-29 06:21:04 +00:00
|
|
|
|
|
|
|
{- Runs an IO action on a selected field of the AssistantData. -}
|
|
|
|
(<<~) :: (a -> IO b) -> (AssistantData -> a) -> Assistant b
|
|
|
|
io <<~ v = reader v >>= liftIO . io
|
2013-01-26 03:14:32 +00:00
|
|
|
|
|
|
|
debug :: [String] -> Assistant ()
|
|
|
|
debug = logaction debugM
|
|
|
|
|
|
|
|
notice :: [String] -> Assistant ()
|
|
|
|
notice = logaction noticeM
|
|
|
|
|
|
|
|
logaction :: (String -> String -> IO ()) -> [String] -> Assistant ()
|
|
|
|
logaction a ws = do
|
2013-01-26 06:09:33 +00:00
|
|
|
ThreadName name <- getAssistant threadName
|
2013-01-26 03:14:32 +00:00
|
|
|
liftIO $ a name $ unwords $ (name ++ ":") : ws
|