@@ -18,93 +18,102 @@ module System.Nix.Store.Remote
1818 , justdoit
1919 ) where
2020
21+ import Control.Monad.Catch (MonadMask )
22+ import Control.Monad.Conc.Class (MonadConc )
23+ import Control.Monad.IO.Class (MonadIO , liftIO )
2124import Data.Default.Class (Default (def ))
2225import Network.Socket (Family , SockAddr (SockAddrUnix ))
2326import System.Nix.Store.Types (FileIngestionMethod (.. ), RepairMode (.. ))
24- import System.Nix.StorePath (StoreDir )
25- import System.Nix.Store.Remote.MonadStore (RemoteStoreT , getStoreDir , RemoteStoreError (RemoteStoreError_GetAddrInfoFailed ))
27+ import System.Nix.Store.Remote.MonadStore
28+ ( runRemoteStoreT
29+ , MonadRemoteStore (.. )
30+ , RemoteStoreT
31+ , RemoteStoreError (RemoteStoreError_GetAddrInfoFailed ))
2632import System.Nix.Store.Remote.Client
2733import System.Nix.Store.Remote.Types
2834
29- import qualified Control.Exception
35+ import qualified Control.Monad.Catch
3036import qualified Network.Socket
37+ import qualified System.Directory
3138
3239-- wip daemon
33- import Control.Monad.Conc.Class (MonadConc )
34- import Control.Monad.IO.Class (MonadIO , liftIO )
35- import Control.Monad.Trans.Control (MonadBaseControl )
3640import System.Nix.StorePath (StorePath )
3741import System.Nix.Store.Remote.Server (WorkerHelper , runDaemonSocket )
38- import qualified System.Directory
3942import qualified System.Nix.StorePath
40- import qualified Control.Monad.Catch
4143
4244-- * Compat
4345
44- type MonadStore = RemoteStoreT StoreConfig IO
46+ type MonadStore = RemoteStoreT IO
4547
4648-- * Runners
4749
48- runStore :: MonadStore a -> Run IO a
49- runStore = runStoreOpts defaultSockPath def
50+ runStore
51+ :: ( MonadIO m
52+ , MonadMask m
53+ )
54+ => RemoteStoreT m a
55+ -> Run m a
56+ runStore = runStoreOpts defaultSockPath
5057
5158defaultSockPath :: String
5259defaultSockPath = " /nix/var/nix/daemon-socket/socket"
5360
5461runStoreOpts
55- :: FilePath
56- -> StoreDir
57- -> MonadStore a
58- -> Run IO a
62+ :: ( MonadIO m
63+ , MonadMask m
64+ )
65+ => FilePath
66+ -> RemoteStoreT m a
67+ -> Run m a
5968runStoreOpts socketPath =
6069 runStoreOpts'
6170 Network.Socket. AF_UNIX
6271 (SockAddrUnix socketPath)
6372
6473runStoreOptsTCP
65- :: String
74+ :: ( MonadIO m
75+ , MonadMask m
76+ )
77+ => String
6678 -> Int
67- -> StoreDir
68- -> MonadStore a
69- -> Run IO a
70- runStoreOptsTCP host port sd code = do
71- Network.Socket. getAddrInfo
79+ -> RemoteStoreT m a
80+ -> Run m a
81+ runStoreOptsTCP host port code = do
82+ addrInfo <- liftIO $ Network.Socket. getAddrInfo
7283 (Just Network.Socket. defaultHints)
7384 (Just host)
7485 (Just $ show port)
75- >>= \ case
86+ case addrInfo of
7687 (sockAddr: _) ->
7788 runStoreOpts'
7889 (Network.Socket. addrFamily sockAddr)
7990 (Network.Socket. addrAddress sockAddr)
80- sd
8191 code
8292 _ -> pure (Left RemoteStoreError_GetAddrInfoFailed , mempty )
8393
8494runStoreOpts'
85- :: Family
95+ :: ( MonadIO m
96+ , MonadMask m
97+ )
98+ => Family
8699 -> SockAddr
87- -> StoreDir
88- -> MonadStore a
89- -> Run IO a
90- runStoreOpts' sockFamily sockAddr storeRootDir code =
91- Control.Exception. bracket
92- open
93- (Network.Socket. close . hasStoreSocket)
94- (flip runStoreSocket code)
100+ -> RemoteStoreT m a
101+ -> Run m a
102+ runStoreOpts' sockFamily sockAddr code =
103+ Control.Monad.Catch. bracket
104+ (liftIO open)
105+ (liftIO . Network.Socket. close . hasStoreSocket)
106+ (\ s -> runRemoteStoreT s $ runStoreSocket code)
95107 where
96108 open = do
97109 soc <- Network.Socket. socket sockFamily Network.Socket. Stream 0
98110 Network.Socket. connect soc sockAddr
99- pure PreStoreConfig
100- { preStoreConfig_socket = soc
101- , preStoreConfig_dir = storeRootDir
102- }
111+ pure soc
103112
104113justdoit :: Run IO (Bool , Bool )
105114justdoit = do
106- runDaemonOpts def handler " /tmp/dsock" $
107- runStoreOpts " /tmp/dsock" def
115+ runDaemonOpts handler " /tmp/dsock" $
116+ runStoreOpts " /tmp/dsock"
108117 $ do
109118 a <- isValidPath pth
110119 b <- isValidPath pth
@@ -125,28 +134,28 @@ justdoit = do
125134runDaemon
126135 :: forall m a
127136 . ( MonadIO m
128- , MonadBaseControl IO m
129137 , MonadConc m
130138 )
131139 => WorkerHelper m
132140 -> m a
133141 -> m a
134- runDaemon workerHelper k = runDaemonOpts def workerHelper defaultSockPath k
142+ runDaemon workerHelper =
143+ runDaemonOpts
144+ workerHelper
145+ defaultSockPath
135146
136147-- | Run an emulated nix daemon on given socket address.
137148-- the deamon will close when the continuation returns.
138149runDaemonOpts
139150 :: forall m a
140151 . ( MonadIO m
141- , MonadBaseControl IO m
142152 , MonadConc m
143153 )
144- => StoreDir
145- -> WorkerHelper m
154+ => WorkerHelper m
146155 -> FilePath
147156 -> m a
148157 -> m a
149- runDaemonOpts sd workerHelper f k = Control.Monad.Catch. bracket
158+ runDaemonOpts workerHelper f k = Control.Monad.Catch. bracket
150159 (liftIO
151160 $ Network.Socket. socket
152161 Network.Socket. AF_UNIX
@@ -157,14 +166,5 @@ runDaemonOpts sd workerHelper f k = Control.Monad.Catch.bracket
157166 $ \ lsock -> do
158167 -- ^ ^^^^^^^^^^^
159168 -- TODO: this: --------------------------------------------------////////////
160- -- should really be
161- -- a file lock followed by unlink *before* bind rather than after close. If
162- -- the program crashes (or loses power or something) then a stale unix
163- -- socket will stick around and prevent the daemon from starting. using a
164- -- lock file instead means only one "copy" of the daemon can hold the lock,
165- -- and can safely unlink the socket before binding no matter how shutdown
166- -- occured.
167-
168- -- set up the listening socket
169169 liftIO $ Network.Socket. bind lsock (SockAddrUnix f)
170- runDaemonSocket sd workerHelper lsock k
170+ runDaemonSocket workerHelper lsock k
0 commit comments