Skip to content

Commit 7b41967

Browse files
committed
remote: monadic collapse
1 parent 4562922 commit 7b41967

File tree

10 files changed

+332
-385
lines changed

10 files changed

+332
-385
lines changed

hnix-store-remote/hnix-store-remote.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ library
123123
, time
124124
, transformers
125125
, network
126-
, monad-control
127126
, mtl
128127
, QuickCheck
129128
, unordered-containers
@@ -206,6 +205,7 @@ test-suite remote-io
206205
, containers
207206
, crypton
208207
, directory
208+
, exceptions
209209
, filepath
210210
, hspec
211211
, hspec-expectations-lifted

hnix-store-remote/src/System/Nix/Store/Remote.hs

Lines changed: 54 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
2124
import Data.Default.Class (Default(def))
2225
import Network.Socket (Family, SockAddr(SockAddrUnix))
2326
import 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))
2632
import System.Nix.Store.Remote.Client
2733
import System.Nix.Store.Remote.Types
2834

29-
import qualified Control.Exception
35+
import qualified Control.Monad.Catch
3036
import 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)
3640
import System.Nix.StorePath (StorePath)
3741
import System.Nix.Store.Remote.Server (WorkerHelper, runDaemonSocket)
38-
import qualified System.Directory
3942
import 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

5158
defaultSockPath :: String
5259
defaultSockPath = "/nix/var/nix/daemon-socket/socket"
5360

5461
runStoreOpts
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
5968
runStoreOpts socketPath =
6069
runStoreOpts'
6170
Network.Socket.AF_UNIX
6271
(SockAddrUnix socketPath)
6372

6473
runStoreOptsTCP
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

8494
runStoreOpts'
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

104113
justdoit :: Run IO (Bool, Bool)
105114
justdoit = 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
125134
runDaemon
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.
138149
runDaemonOpts
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

hnix-store-remote/src/System/Nix/Store/Remote/Client/Core.hs

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,8 @@ import Data.Some (Some(Some))
1212
import System.Nix.Nar (NarSource)
1313
import System.Nix.Store.Remote.Logger (processOutput)
1414
import System.Nix.Store.Remote.MonadStore
15-
( MonadRemoteStore
15+
( MonadRemoteStore(..)
1616
, RemoteStoreError(..)
17-
, RemoteStoreT
18-
, runRemoteStoreT
19-
, mapStoreConfig
20-
, takeNarSource
21-
, getStoreSocket
2217
)
2318
import System.Nix.Store.Remote.Socket (sockPutS, sockGetS)
2419
import System.Nix.Store.Remote.Serializer
@@ -31,10 +26,9 @@ import System.Nix.Store.Remote.Serializer
3126
, trustedFlag
3227
, workerMagic
3328
)
34-
import System.Nix.Store.Remote.Types.Handshake (ClientHandshakeInput(..), ClientHandshakeOutput(..))
29+
import System.Nix.Store.Remote.Types.Handshake (ClientHandshakeOutput(..))
3530
import System.Nix.Store.Remote.Types.Logger (Logger)
36-
import System.Nix.Store.Remote.Types.ProtoVersion (ProtoVersion(..), ourProtoVersion)
37-
import System.Nix.Store.Remote.Types.StoreConfig (PreStoreConfig, StoreConfig, preStoreConfigToStoreConfig)
31+
import System.Nix.Store.Remote.Types.ProtoVersion (ProtoVersion(..))
3832
import System.Nix.Store.Remote.Types.StoreRequest (StoreRequest(..))
3933
import System.Nix.Store.Remote.Types.StoreReply (StoreReply(..))
4034
import System.Nix.Store.Remote.Types.WorkerMagic (WorkerMagic(..))
@@ -85,31 +79,21 @@ doReq = \case
8579
)
8680

8781
runStoreSocket
88-
:: ( Monad m
89-
, MonadIO m
90-
)
91-
=> PreStoreConfig
92-
-> RemoteStoreT StoreConfig m a
93-
-> Run m a
94-
runStoreSocket preStoreConfig code =
95-
runRemoteStoreT preStoreConfig $ do
82+
:: MonadRemoteStore m
83+
=> m a
84+
-> m a
85+
runStoreSocket code = do
9686
ClientHandshakeOutput{..}
9787
<- greet
98-
ClientHandshakeInput
99-
{ clientHandshakeInputOurVersion = ourProtoVersion
100-
}
10188

102-
mapStoreConfig
103-
(preStoreConfigToStoreConfig
104-
clientHandshakeOutputLeastCommonVerison)
105-
code
89+
setProtoVersion clientHandshakeOutputLeastCommonVersion
90+
code
10691

10792
where
10893
greet
109-
:: MonadIO m
110-
=> ClientHandshakeInput
111-
-> RemoteStoreT PreStoreConfig m ClientHandshakeOutput
112-
greet ClientHandshakeInput{..} = do
94+
:: MonadRemoteStore m
95+
=> m ClientHandshakeOutput
96+
greet = do
11397

11498
sockPutS
11599
(mapErrorS
@@ -133,9 +117,10 @@ runStoreSocket preStoreConfig code =
133117
when (daemonVersion < ProtoVersion 1 10)
134118
$ throwError RemoteStoreError_ClientVersionTooOld
135119

136-
sockPutS protoVersion clientHandshakeInputOurVersion
120+
pv <- getProtoVersion
121+
sockPutS protoVersion pv
137122

138-
let leastCommonVersion = min daemonVersion ourProtoVersion
123+
let leastCommonVersion = min daemonVersion pv
139124

140125
when (leastCommonVersion >= ProtoVersion 1 14)
141126
$ sockPutS int (0 :: Int) -- affinity, obsolete
@@ -162,9 +147,8 @@ runStoreSocket preStoreConfig code =
162147
$ mapErrorS RemoteStoreError_SerializerHandshake trustedFlag
163148
else pure Nothing
164149

165-
mapStoreConfig
166-
(preStoreConfigToStoreConfig leastCommonVersion)
167-
processOutput
150+
setProtoVersion leastCommonVersion
151+
processOutput
168152

169153
pure ClientHandshakeOutput
170154
{ clientHandshakeOutputNixVersion = daemonNixVersion

0 commit comments

Comments
 (0)