d71c65ca0a
This is similar to the pusher thread, but a separate thread because git pushes can be done in parallel with exports, and updating a big export should not prevent other git pushes going out in the meantime. The exportThread only runs at most every 30 seconds, since updating an export is more expensive than pushing. This may need to be tuned. Added a separate channel for export commits; the committer records a commit in that channel. Also, reconnectRemotes records a dummy commit, to make the exporter thread wake up and make sure all exports are up-to-date. So, connecting a drive with a directory special remote export will immediately update it, and getting online will automatically update S3 and WebDAV exports. The transfer queue is not involved in exports. Instead, failed exports are retried much like failed pushes. This commit was sponsored by Ewen McNeill.
50 lines
1.7 KiB
Haskell
50 lines
1.7 KiB
Haskell
{- git-annex assistant git pushing thread
|
|
-
|
|
- Copyright 2012 Joey Hess <id@joeyh.name>
|
|
-
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
-}
|
|
|
|
module Assistant.Threads.Pusher where
|
|
|
|
import Assistant.Common
|
|
import Assistant.Commits
|
|
import Assistant.Pushes
|
|
import Assistant.DaemonStatus
|
|
import Assistant.Sync
|
|
import Utility.ThreadScheduler
|
|
import qualified Remote
|
|
import qualified Types.Remote as Remote
|
|
|
|
{- This thread retries pushes that failed before. -}
|
|
pushRetryThread :: NamedThread
|
|
pushRetryThread = namedThread "PushRetrier" $ runEvery (Seconds halfhour) <~> do
|
|
-- We already waited half an hour, now wait until there are failed
|
|
-- pushes to retry.
|
|
topush <- getFailedPushesBefore (fromIntegral halfhour)
|
|
=<< getAssistant failedPushMap
|
|
unless (null topush) $ do
|
|
debug ["retrying", show (length topush), "failed pushes"]
|
|
void $ pushToRemotes topush
|
|
where
|
|
halfhour = 1800
|
|
|
|
{- This thread pushes git commits out to remotes soon after they are made. -}
|
|
pushThread :: NamedThread
|
|
pushThread = namedThread "Pusher" $ runEvery (Seconds 2) <~> do
|
|
-- We already waited two seconds as a simple rate limiter.
|
|
-- Next, wait until at least one commit has been made
|
|
void getCommits
|
|
-- Now see if now's a good time to push.
|
|
void $ pushToRemotes =<< pushTargets
|
|
|
|
{- We want to avoid pushing to remotes that are marked readonly.
|
|
-
|
|
- Also, avoid pushing to local remotes we can easily tell are not available,
|
|
- to avoid ugly messages when a removable drive is not attached.
|
|
-}
|
|
pushTargets :: Assistant [Remote]
|
|
pushTargets = liftIO . filterM (Remote.checkAvailable True)
|
|
=<< candidates <$> getDaemonStatus
|
|
where
|
|
candidates = filter (not . Remote.readonly) . syncGitRemotes
|