1{- git check-attr interface
2 -
3 - Copyright 2012-2020 Joey Hess <id@joeyh.name>
4 -
5 - Licensed under the GNU AGPL version 3 or higher.
6 -}
7
8module Annex.CheckAttr (
9	checkAttr,
10	checkAttrs,
11	checkAttrStop,
12	mkConcurrentCheckAttrHandle,
13) where
14
15import Annex.Common
16import qualified Git.CheckAttr as Git
17import qualified Annex
18import Utility.ResourcePool
19import Types.Concurrency
20import Annex.Concurrent.Utility
21
22{- All gitattributes used by git-annex. -}
23annexAttrs :: [Git.Attr]
24annexAttrs =
25	[ "annex.backend"
26	, "annex.largefiles"
27	, "annex.numcopies"
28	, "annex.mincopies"
29	]
30
31checkAttr :: Git.Attr -> RawFilePath -> Annex String
32checkAttr attr file = withCheckAttrHandle $ \h ->
33	liftIO $ Git.checkAttr h attr file
34
35checkAttrs :: [Git.Attr] -> RawFilePath -> Annex [String]
36checkAttrs attrs file = withCheckAttrHandle $ \h ->
37	liftIO $ Git.checkAttrs h attrs file
38
39withCheckAttrHandle :: (Git.CheckAttrHandle -> Annex a) -> Annex a
40withCheckAttrHandle a =
41	maybe mkpool go =<< Annex.getState Annex.checkattrhandle
42  where
43	go p = withResourcePool p start a
44	start = inRepo $ Git.checkAttrStart annexAttrs
45	mkpool = do
46		-- This only runs in non-concurrent code paths;
47		-- a concurrent pool is set up earlier when needed.
48		p <- mkResourcePoolNonConcurrent start
49		Annex.changeState $ \s -> s { Annex.checkattrhandle = Just p }
50		go p
51
52mkConcurrentCheckAttrHandle :: Concurrency -> Annex (ResourcePool Git.CheckAttrHandle)
53mkConcurrentCheckAttrHandle c =
54	Annex.getState Annex.checkattrhandle >>= \case
55		Just p@(ResourcePool {}) -> return p
56		_ -> mkResourcePool =<< liftIO (maxCheckAttrs c)
57
58{- git check-attr is typically CPU bound, and is not likely to be the main
59 - bottleneck for any command. So limit to the number of CPU cores, maximum,
60 - while respecting the -Jn value.
61 -}
62maxCheckAttrs :: Concurrency -> IO Int
63maxCheckAttrs = concurrencyUpToCpus
64
65checkAttrStop :: Annex ()
66checkAttrStop = maybe noop stop =<< Annex.getState Annex.checkattrhandle
67  where
68	stop p = do
69		liftIO $ freeResourcePool p Git.checkAttrStop
70		Annex.changeState $ \s -> s { Annex.checkattrhandle = Nothing }
71