aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-10-26 12:42:58 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-10-26 12:42:58 -0400
commit956694b88fff7bc151bad6196ed429e0db7b23cb (patch)
tree07237216bb2c9854d19a3664413b1311f472ad27
parentfdec6d27c4d32b9d641d17336b6be4a91c1d3fc4 (diff)
assistant: When autostarted, wait 5 seconds before running the startup scan, to avoid contending with the user's desktop login process.
-rw-r--r--Assistant.hs7
-rw-r--r--Assistant/Threads/SanityChecker.hs21
-rw-r--r--Command/Assistant.hs41
-rw-r--r--Command/Watch.hs9
-rw-r--r--Command/WebApp.hs4
-rw-r--r--debian/changelog7
-rw-r--r--doc/bugs/Too_much_system_load_on_startup.mdwn4
7 files changed, 61 insertions, 32 deletions
diff --git a/Assistant.hs b/Assistant.hs
index 8a0c574ab..5eeba818e 100644
--- a/Assistant.hs
+++ b/Assistant.hs
@@ -48,6 +48,7 @@ import Assistant.Types.UrlRenderer
import qualified Utility.Daemon
import Utility.LogFile
import Utility.ThreadScheduler
+import Utility.HumanTime
import qualified Build.SysConfig as SysConfig
import System.Log.Logger
@@ -61,8 +62,8 @@ stopDaemon = liftIO . Utility.Daemon.stopDaemon =<< fromRepo gitAnnexPidFile
-
- startbrowser is passed the url and html shim file, as well as the original
- stdout and stderr descriptors. -}
-startDaemon :: Bool -> Bool -> Maybe HostName -> Maybe (Maybe Handle -> Maybe Handle -> String -> FilePath -> IO ()) -> Annex ()
-startDaemon assistant foreground listenhost startbrowser = do
+startDaemon :: Bool -> Bool -> Maybe Duration -> Maybe HostName -> Maybe (Maybe Handle -> Maybe Handle -> String -> FilePath -> IO ()) -> Annex ()
+startDaemon assistant foreground startdelay listenhost startbrowser = do
Annex.changeState $ \s -> s { Annex.daemon = True }
pidfile <- fromRepo gitAnnexPidFile
logfile <- fromRepo gitAnnexLogFile
@@ -140,7 +141,7 @@ startDaemon assistant foreground listenhost startbrowser = do
, watch $ watchThread
-- must come last so that all threads that wait
-- on it have already started waiting
- , watch $ sanityCheckerStartupThread
+ , watch $ sanityCheckerStartupThread startdelay
]
liftIO waitForTermination
diff --git a/Assistant/Threads/SanityChecker.hs b/Assistant/Threads/SanityChecker.hs
index b3aa9ddfd..d8ffa41f4 100644
--- a/Assistant/Threads/SanityChecker.hs
+++ b/Assistant/Threads/SanityChecker.hs
@@ -25,15 +25,22 @@ import Utility.NotificationBroadcaster
import Config
import qualified Git
import qualified Utility.Lsof as Lsof
+import Utility.HumanTime
import Data.Time.Clock.POSIX
{- This thread runs once at startup, and most other threads wait for it
- to finish. (However, the webapp thread does not, to prevent the UI
- being nonresponsive.) -}
-sanityCheckerStartupThread :: NamedThread
-sanityCheckerStartupThread = namedThreadUnchecked "SanityCheckerStartup" $
- startupCheck
+sanityCheckerStartupThread :: Maybe Duration -> NamedThread
+sanityCheckerStartupThread startupdelay = namedThreadUnchecked "SanityCheckerStartup" $ do
+ checkStaleGitLocks
+
+ liftIO $ maybe noop (threadDelaySeconds . Seconds . fromIntegral . durationSeconds) startupdelay
+
+ {- Notify other threads that the startup sanity check is done. -}
+ status <- getDaemonStatus
+ liftIO $ sendNotification $ startupSanityCheckNotifier status
{- This thread wakes up hourly for inxepensive frequent sanity checks. -}
sanityCheckerHourlyThread :: NamedThread
@@ -80,14 +87,6 @@ waitForNextCheck = do
oneDay - truncate (now - lastcheck)
| otherwise = oneDay
-startupCheck :: Assistant ()
-startupCheck = do
- checkStaleGitLocks
-
- {- Notify other threads that the startup sanity check is done. -}
- status <- getDaemonStatus
- liftIO $ sendNotification $ startupSanityCheckNotifier status
-
{- It's important to stay out of the Annex monad as much as possible while
- running potentially expensive parts of this check, since remaining in it
- will block the watcher. -}
diff --git a/Command/Assistant.hs b/Command/Assistant.hs
index f65bed736..521a88571 100644
--- a/Command/Assistant.hs
+++ b/Command/Assistant.hs
@@ -14,43 +14,55 @@ import qualified Command.Watch
import Init
import Config.Files
import qualified Build.SysConfig
+import Utility.HumanTime
import System.Environment
def :: [Command]
-def = [noRepo checkAutoStart $ dontCheck repoExists $
- withOptions [Command.Watch.foregroundOption, Command.Watch.stopOption, autoStartOption] $
+def = [noRepo checkAutoStart $ dontCheck repoExists $ withOptions options $
command "assistant" paramNothing seek SectionCommon
"automatically handle changes"]
+options :: [Option]
+options =
+ [ Command.Watch.foregroundOption
+ , Command.Watch.stopOption
+ , autoStartOption
+ , startDelayOption
+ ]
+
autoStartOption :: Option
autoStartOption = Option.flag [] "autostart" "start in known repositories"
+startDelayOption :: Option
+startDelayOption = Option.field [] "startdelay" paramNumber "delay before running startup scan"
+
seek :: [CommandSeek]
seek = [withFlag Command.Watch.stopOption $ \stopdaemon ->
withFlag Command.Watch.foregroundOption $ \foreground ->
withFlag autoStartOption $ \autostart ->
- withNothing $ start foreground stopdaemon autostart]
+ withField startDelayOption (pure . maybe Nothing parseDuration) $ \startdelay ->
+ withNothing $ start foreground stopdaemon autostart startdelay]
-start :: Bool -> Bool -> Bool -> CommandStart
-start foreground stopdaemon autostart
+start :: Bool -> Bool -> Bool -> Maybe Duration -> CommandStart
+start foreground stopdaemon autostart startdelay
| autostart = do
- liftIO autoStart
+ liftIO $ autoStart startdelay
stop
| otherwise = do
ensureInitialized
- Command.Watch.start True foreground stopdaemon
+ Command.Watch.start True foreground stopdaemon startdelay
{- Run outside a git repository. Check to see if any parameter is
- --autostart and enter autostart mode. -}
checkAutoStart :: IO ()
checkAutoStart = ifM (elem "--autostart" <$> getArgs)
- ( autoStart
+ ( autoStart Nothing
, error "Not in a git repository."
)
-autoStart :: IO ()
-autoStart = do
+autoStart :: Maybe Duration -> IO ()
+autoStart startdelay = do
dirs <- liftIO readAutoStartFile
when (null dirs) $ do
f <- autoStartFile
@@ -67,5 +79,10 @@ autoStart = do
go haveionice program dir = do
setCurrentDirectory dir
if haveionice
- then boolSystem "ionice" [Param "-c3", Param program, Param "assistant"]
- else boolSystem program [Param "assistant"]
+ then boolSystem "ionice" (Param "-c3" : Param program : baseparams)
+ else boolSystem program baseparams
+ where
+ baseparams =
+ [ Param "assistant"
+ , Param $ "--startdelay=" ++ fromDuration (fromMaybe (Duration 5) startdelay)
+ ]
diff --git a/Command/Watch.hs b/Command/Watch.hs
index c5fd1a8cd..0b34b0f84 100644
--- a/Command/Watch.hs
+++ b/Command/Watch.hs
@@ -11,6 +11,7 @@ import Common.Annex
import Assistant
import Command
import Option
+import Utility.HumanTime
def :: [Command]
def = [notBareRepo $ withOptions [foregroundOption, stopOption] $
@@ -19,7 +20,7 @@ def = [notBareRepo $ withOptions [foregroundOption, stopOption] $
seek :: [CommandSeek]
seek = [withFlag stopOption $ \stopdaemon ->
withFlag foregroundOption $ \foreground ->
- withNothing $ start False foreground stopdaemon]
+ withNothing $ start False foreground stopdaemon Nothing]
foregroundOption :: Option
foregroundOption = Option.flag [] "foreground" "do not daemonize"
@@ -27,9 +28,9 @@ foregroundOption = Option.flag [] "foreground" "do not daemonize"
stopOption :: Option
stopOption = Option.flag [] "stop" "stop daemon"
-start :: Bool -> Bool -> Bool -> CommandStart
-start assistant foreground stopdaemon = do
+start :: Bool -> Bool -> Bool -> Maybe Duration -> CommandStart
+start assistant foreground stopdaemon startdelay = do
if stopdaemon
then stopDaemon
- else startDaemon assistant foreground Nothing Nothing -- does not return
+ else startDaemon assistant foreground startdelay Nothing Nothing -- does not return
stop
diff --git a/Command/WebApp.hs b/Command/WebApp.hs
index 6577ce02b..88c1537d0 100644
--- a/Command/WebApp.hs
+++ b/Command/WebApp.hs
@@ -69,7 +69,7 @@ start' allowauto listenhost = do
url <- liftIO . readFile
=<< fromRepo gitAnnexUrlFile
liftIO $ openBrowser browser f url Nothing Nothing
- , startDaemon True True listenhost $ Just $
+ , startDaemon True True Nothing listenhost $ Just $
\origout origerr url htmlshim ->
if isJust listenhost
then maybe noop (`hPutStrLn` url) origout
@@ -155,7 +155,7 @@ firstRun listenhost = do
_wait <- takeMVar v
state <- Annex.new =<< Git.CurrentRepo.get
Annex.eval state $
- startDaemon True True listenhost $ Just $
+ startDaemon True True Nothing listenhost $ Just $
sendurlback v
sendurlback v _origout _origerr url _htmlshim = do
recordUrl url
diff --git a/debian/changelog b/debian/changelog
index a38466dd8..5c28b729a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+git-annex (4.20131025) UNRELEASED; urgency=low
+
+ * assistant: When autostarted, wait 5 seconds before running the startup
+ scan, to avoid contending with the user's desktop login process.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 26 Oct 2013 12:11:48 -0400
+
git-annex (4.20131024) unstable; urgency=low
* webapp: Fix bug when adding a remote and git-remote-gcrypt
diff --git a/doc/bugs/Too_much_system_load_on_startup.mdwn b/doc/bugs/Too_much_system_load_on_startup.mdwn
index 9ee63f6d7..fc514ca73 100644
--- a/doc/bugs/Too_much_system_load_on_startup.mdwn
+++ b/doc/bugs/Too_much_system_load_on_startup.mdwn
@@ -18,3 +18,7 @@ to
Exec=sleep 5 ionice -c 3 /usr/bin/git-annex assistant --autostart
This delays the start of git-annex for 5 seconds, letting the desktop get started, and forces git-annex to yield IO to other programs -preventing it from slowing them down by forcing them to wait for disk access. Since this is a background daemon with potentially high IO usage, but no need for quick responsiveness, perhaps that would make a decent default?
+
+> Added 5 second delay to existing ionice. Provisionally [[done]],
+> although it does occur to me that the startup scan could add some delays
+> in between actions to run more as a batch job. --[[Joey]]