probeLockSupport = withEventuallyCleanedOtherTmp $ \tmp -> do
let f = tmp P.</> "lockprobe"
mode <- annexFileMode
- liftIO $ withAsync warnstall (const (go f mode))
+ annexrunner <- Annex.makeRunner
+ liftIO $ withAsync (warnstall annexrunner) (const (go f mode))
where
go f mode = do
removeWhenExistsWith R.removeLink f
removeWhenExistsWith R.removeLink f
return ok
- warnstall = do
+ warnstall annexrunner = do
threadDelaySeconds (Seconds 10)
- warningIO "Probing the filesystem for POSIX fcntl lock support is taking a long time."
- warningIO "(Setting annex.pidlock will avoid this probe.)"
+ annexrunner $ do
+ warning "Probing the filesystem for POSIX fcntl lock support is taking a long time."
+ warning "(Setting annex.pidlock will avoid this probe.)"
#endif
probeFifoSupport :: Annex Bool
`onException` store UncheckedExternalAsync
if asyncExtensionEnabled extensions
then do
- relay <- liftIO $ runRelayToExternalAsync external st
+ annexrunner <- Annex.makeRunner
+ relay <- liftIO $ runRelayToExternalAsync external st annexrunner
st' <- liftIO $ asyncRelayExternalState relay
store (ExternalAsync relay)
return st'
module Remote.External.AsyncExtension (runRelayToExternalAsync) where
import Common
+import Annex
import Messages
import Remote.External.Types
-import Utility.SimpleProtocol as Proto
+import qualified Utility.SimpleProtocol as Proto
import Control.Concurrent.Async
import Control.Concurrent.STM
-- | Starts a thread that will handle all communication with the external
-- process. The input ExternalState communicates directly with the external
-- process.
-runRelayToExternalAsync :: External -> ExternalState -> IO ExternalAsyncRelay
-runRelayToExternalAsync external st = do
+runRelayToExternalAsync :: External -> ExternalState -> (Annex () -> IO ()) -> IO ExternalAsyncRelay
+runRelayToExternalAsync external st annexrunner = do
jidmap <- newTVarIO M.empty
sendq <- newSendQueue
nextjid <- newTVarIO (JobId 1)
sender <- async $ sendloop st sendq
- receiver <- async $ receiveloop external st jidmap sendq sender
+ receiver <- async $ receiveloop external st jidmap sendq sender annexrunner
return $ ExternalAsyncRelay $ do
receiveq <- newReceiveQueue
jid <- atomically $ do
newSendQueue :: IO SendQueue
newSendQueue = newTBMChanIO 10
-receiveloop :: External -> ExternalState -> JidMap -> SendQueue -> Async () -> IO ()
-receiveloop external st jidmap sendq sendthread = externalReceive st >>= \case
+receiveloop :: External -> ExternalState -> JidMap -> SendQueue -> Async () -> (Annex () -> IO ()) -> IO ()
+receiveloop external st jidmap sendq sendthread annexrunner = externalReceive st >>= \case
Just l -> case parseMessage l :: Maybe AsyncMessage of
Just (AsyncMessage jid msg) ->
M.lookup jid <$> readTVarIO jidmap >>= \case
Just c -> do
atomically $ writeTBMChan c msg
- receiveloop external st jidmap sendq sendthread
+ receiveloop external st jidmap sendq sendthread annexrunner
Nothing -> protoerr "unknown job number"
Nothing -> case parseMessage l :: Maybe ExceptionalMessage of
Just _ -> do
m <- readTVarIO jidmap
forM_ (M.elems m) $ \c ->
atomically $ writeTBMChan c l
- receiveloop external st jidmap sendq sendthread
+ receiveloop external st jidmap sendq sendthread annexrunner
Nothing -> protoerr "unexpected non-async message"
Nothing -> closeandshutdown
where
protoerr s = do
- warningIO $ "async external special remote protocol error: " ++ s
+ annexrunner $ warning $ "async external special remote protocol error: " ++ s
closeandshutdown
closeandshutdown = do
- But this is the best that can be done with the storer interface that
- writes a whole L.ByteString at a time.
-}
-storeChunked :: ChunkSize -> [FilePath] -> (FilePath -> L.ByteString -> IO ()) -> L.ByteString -> IO [FilePath]
-storeChunked chunksize dests storer content =
+storeChunked :: (Annex () -> IO ()) -> ChunkSize -> [FilePath] -> (FilePath -> L.ByteString -> IO ()) -> L.ByteString -> IO [FilePath]
+storeChunked annexrunner chunksize dests storer content =
either onerr return =<< tryNonAsync (go (Just chunksize) dests)
where
go _ [] = return [] -- no dests!?
| otherwise = storechunks sz [] dests content
onerr e = do
- warningIO (show e)
+ annexrunner $ warning (show e)
return []
storechunks _ _ [] _ = return [] -- ran out of dests
import Types.Remote
import Types.Export
import qualified Git
+import qualified Annex
import Config
import Config.Cost
import Annex.SpecialRemote.Config
store :: DavHandleVar -> ChunkConfig -> Storer
store hv (LegacyChunks chunksize) = fileStorer $ \k f p ->
- withDavHandle hv $ \dav -> liftIO $
- withMeteredFile f p $ storeLegacyChunked chunksize k dav
+ withDavHandle hv $ \dav -> do
+ annexrunner <- Annex.makeRunner
+ liftIO $ withMeteredFile f p $ storeLegacyChunked annexrunner chunksize k dav
store hv _ = httpStorer $ \k reqbody ->
withDavHandle hv $ \dav -> liftIO $ goDAV dav $ do
let tmp = keyTmpLocation k
-- Legacy chunking code, to be removed eventually.
--
-storeLegacyChunked :: ChunkSize -> Key -> DavHandle -> L.ByteString -> IO ()
-storeLegacyChunked chunksize k dav b =
+storeLegacyChunked :: (Annex () -> IO ()) -> ChunkSize -> Key -> DavHandle -> L.ByteString -> IO ()
+storeLegacyChunked annexrunner chunksize k dav b =
Legacy.storeChunks k tmp dest storer recorder finalizer
where
storehttp l b' = void $ goDAV dav $ do
maybe noop (void . mkColRecursive) (locationParent l)
debugDav $ "putContent " ++ l
inLocation l $ putContentM (contentType, b')
- storer locs = Legacy.storeChunked chunksize locs storehttp b
+ storer locs = Legacy.storeChunked annexrunner chunksize locs storehttp b
recorder l s = storehttp l (L8.fromString s)
finalizer tmp' dest' = goDAV dav $
finalizeStore dav tmp' (fromJust $ locationParent dest')