Skip to content

Commit 63fd634

Browse files
committed
Lift the monad stack to a monad stack transformer
1 parent a139b6f commit 63fd634

File tree

6 files changed

+96
-62
lines changed

6 files changed

+96
-62
lines changed

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,22 @@ library
3030
, System.Nix.Store.Remote.Types
3131
, System.Nix.Store.Remote.Util
3232

33-
build-depends: base >=4.10 && <5
34-
, attoparsec
35-
, bytestring
33+
build-depends: attoparsec
34+
, base >=4.10 && <5
3635
, binary
3736
, bytestring
3837
, containers
3938
, filepath
40-
, text
41-
, unix
39+
, hnix-store-core
40+
, lifted-base
41+
, monad-control
42+
, mtl
4243
, network
4344
, nix-derivation >= 1.1.1 && <2
44-
, mtl
45-
, unordered-containers
46-
, filepath
45+
, text
4746
, time
48-
, hnix-store-core
47+
, unix
48+
, unordered-containers
4949
, vector
5050
hs-source-dirs: src
5151
default-language: Haskell2010

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
{-# LANGUAGE RecordWildCards #-}
1010
module System.Nix.Store.Remote
1111
(
12-
addToStore
12+
MonadStoreT
13+
, MonadStore
14+
, addToStore
1315
, addToStoreNar
1416
, addTextToStore
1517
, addSignatures
@@ -38,6 +40,7 @@ module System.Nix.Store.Remote
3840
where
3941

4042
import Control.Monad (void, unless, when)
43+
import Control.Monad.IO.Class (MonadIO)
4144
import Data.ByteString.Lazy (ByteString)
4245
import Data.Map.Strict (Map)
4346
import Data.Text (Text)
@@ -74,13 +77,13 @@ type CheckSigsFlag = Bool
7477
type SubstituteFlag = Bool
7578

7679
-- | Pack `FilePath` as `Nar` and add it to the store.
77-
addToStore :: forall a. (ValidAlgo a, NamedAlgo a)
80+
addToStore :: forall a m. (ValidAlgo a, NamedAlgo a, MonadIO m)
7881
=> StorePathName -- ^ Name part of the newly created `StorePath`
7982
-> FilePath -- ^ Local `FilePath` to add
8083
-> Bool -- ^ Add target directory recursively
8184
-> (FilePath -> Bool) -- ^ Path filter function
8285
-> RepairFlag -- ^ Only used by local store backend
83-
-> MonadStore StorePath
86+
-> MonadStoreT m StorePath
8487
addToStore name pth recursive _pathFilter _repair = do
8588

8689
nar :: ByteString <- Control.Monad.IO.Class.liftIO
@@ -155,11 +158,12 @@ addToStoreNar StorePathMetadata{..} nar repair checkSigs = do
155158
--
156159
-- Reference accepts repair but only uses it
157160
-- to throw error in case of remote talking to nix-daemon.
158-
addTextToStore :: Text -- ^ Name of the text
161+
addTextToStore :: (MonadIO m)
162+
=> Text -- ^ Name of the text
159163
-> Text -- ^ Actual text to add
160164
-> StorePathSet -- ^ Set of `StorePath`s that the added text references
161165
-> RepairFlag -- ^ Repair flag, must be `False` in case of remote backend
162-
-> MonadStore StorePath
166+
-> MonadStoreT m StorePath
163167
addTextToStore name text references' repair = do
164168
when repair $ error "repairing is not supported when building through the Nix daemon"
165169
runOpArgs AddTextToStore $ do
@@ -210,7 +214,7 @@ buildDerivation p drv buildMode = do
210214
-- XXX: reason for this is unknown
211215
-- but without it protocol just hangs waiting for
212216
-- more data. Needs investigation
213-
putInt 0
217+
putInt (0 :: Int)
214218

215219
res <- getSocketIncremental $ getBuildResult
216220
return res
@@ -226,7 +230,7 @@ findRoots = do
226230
sd <- getStoreDir
227231
res <- getSocketIncremental
228232
$ getMany
229-
$ (,) <$> (Data.ByteString.Lazy.fromStrict <$> getByteStringLen)
233+
$ (,) <$> (Data.ByteString.Lazy.fromStrict <$> getByteStringLen)
230234
<*> getPath sd
231235

232236
r <- catRights res

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE RankNTypes #-}
2+
{-# LANGUAGE ScopedTypeVariables #-}
23
module System.Nix.Store.Remote.Logger (
34
Logger(..)
45
, Field(..)
@@ -30,16 +31,16 @@ controlParser = do
3031
0x52534c54 -> Result <$> getInt <*> getInt <*> getFields
3132
x -> fail $ "Invalid control message received:" ++ show x
3233

33-
processOutput :: MonadStore [Logger]
34+
processOutput :: MonadIO m => MonadStoreT m [Logger]
3435
processOutput = go decoder
3536
where decoder = runGetIncremental controlParser
36-
go :: Decoder Logger -> MonadStore [Logger]
37+
go :: MonadIO m => Decoder Logger -> MonadStoreT m [Logger]
3738
go (Done _leftover _consumed ctrl) = do
3839
case ctrl of
3940
e@(Error _ _) -> return [e]
4041
Last -> return [Last]
4142
Read _n -> do
42-
(mdata, _) <- get
43+
(mdata, _) <- NixStore get
4344
case mdata of
4445
Nothing -> throwError "No data to read provided"
4546
Just part -> do
@@ -55,7 +56,7 @@ processOutput = go decoder
5556
next <- go decoder
5657
return $ x:next
5758
go (Partial k) = do
58-
soc <- storeSocket <$> ask
59+
soc <- storeSocket <$> NixStore ask
5960
chunk <- liftIO (Just <$> recv soc 8)
6061
go (k chunk)
6162

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

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{-# LANGUAGE DataKinds #-}
22
{-# LANGUAGE ScopedTypeVariables #-}
33
{-# LANGUAGE TypeApplications #-}
4+
{-# LANGUAGE FlexibleContexts #-}
45
module System.Nix.Store.Remote.Protocol (
56
WorkerOp(..)
67
, simpleOp
@@ -14,6 +15,7 @@ import Control.Exception (bracket)
1415
import Control.Monad.Except
1516
import Control.Monad.Reader
1617
import Control.Monad.State
18+
import Control.Monad.Trans.Control (MonadBaseControl, liftBaseOp)
1719

1820
import Data.Binary.Get
1921
import Data.Binary.Put
@@ -112,25 +114,27 @@ opNum AddToStoreNar = 39
112114
opNum QueryMissing = 40
113115

114116

115-
simpleOp :: WorkerOp -> MonadStore Bool
117+
simpleOp :: (MonadIO m) => WorkerOp -> MonadStoreT m Bool
116118
simpleOp op = do
117119
simpleOpArgs op $ return ()
118120

119-
simpleOpArgs :: WorkerOp -> Put -> MonadStore Bool
121+
simpleOpArgs :: (MonadIO m) => WorkerOp -> Put -> MonadStoreT m Bool
120122
simpleOpArgs op args = do
121123
runOpArgs op args
122124
err <- gotError
123125
case err of
124126
True -> do
125-
Error _num msg <- head <$> getError
126-
throwError $ Data.ByteString.Char8.unpack msg
127+
err <- head <$> getError
128+
case err of
129+
Error _num msg -> throwError $ Data.ByteString.Char8.unpack msg
130+
_ -> throwError $ "Well, it should really be an error by now"
127131
False -> do
128132
sockGetBool
129133

130-
runOp :: WorkerOp -> MonadStore ()
134+
runOp :: (MonadIO m) => WorkerOp -> MonadStoreT m ()
131135
runOp op = runOpArgs op $ return ()
132136

133-
runOpArgs :: WorkerOp -> Put -> MonadStore ()
137+
runOpArgs :: (MonadIO m) => WorkerOp -> Put -> MonadStoreT m ()
134138
runOpArgs op args = do
135139

136140
-- Temporary hack for printing the messages destined for nix-daemon socket
@@ -144,18 +148,21 @@ runOpArgs op args = do
144148
args
145149

146150
out <- processOutput
147-
modify (\(a, b) -> (a, b++out))
151+
NixStore $ modify (\(a, b) -> (a, b++out))
148152
err <- gotError
149153
when err $ do
150-
Error _num msg <- head <$> getError
151-
throwError $ Data.ByteString.Char8.unpack msg
154+
err <- head <$> getError
155+
case err of
156+
Error _num msg -> throwError $ Data.ByteString.Char8.unpack msg
157+
_ -> throwError $ "Well, it should really be an error by now"
152158

153-
runStore :: MonadStore a -> IO (Either String a, [Logger])
159+
160+
runStore :: (MonadIO m, MonadBaseControl IO m) => MonadStoreT m a -> m (Either String a, [Logger])
154161
runStore = runStoreOpts defaultSockPath "/nix/store"
155162

156-
runStoreOpts :: FilePath -> FilePath -> MonadStore a -> IO (Either String a, [Logger])
163+
runStoreOpts :: (MonadIO m, MonadBaseControl IO m) => FilePath -> FilePath -> MonadStoreT m a -> m (Either String a, [Logger])
157164
runStoreOpts sockPath storeRootDir code = do
158-
bracket (open sockPath) (Network.Socket.close . storeSocket) run
165+
liftBaseOp (bracket (open sockPath) (Network.Socket.close . storeSocket)) run
159166
where
160167
open path = do
161168
soc <-
@@ -168,9 +175,10 @@ runStoreOpts sockPath storeRootDir code = do
168175
return $ StoreConfig { storeSocket = soc
169176
, storeDir = storeRootDir }
170177

178+
greet :: MonadIO m => MonadStoreT m [Logger]
171179
greet = do
172180
sockPut $ putInt workerMagic1
173-
soc <- storeSocket <$> ask
181+
soc <- storeSocket <$> NixStore ask
174182
vermagic <- liftIO $ recv soc 16
175183
let (magic2, _daemonProtoVersion) =
176184
flip runGet (Data.ByteString.Lazy.fromStrict vermagic)
@@ -188,4 +196,5 @@ runStoreOpts sockPath storeRootDir code = do
188196
fmap (\(res, (_data, logs)) -> (res, logs))
189197
$ flip runReaderT sock
190198
$ flip runStateT (Nothing, [])
191-
$ runExceptT (greet >> code)
199+
$ runExceptT
200+
$ unStore (greet >> code)

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

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
{-# LANGUAGE KindSignatures #-}
33
{-# LANGUAGE TypeApplications #-}
44
{-# LANGUAGE ScopedTypeVariables #-}
5+
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6+
57
module System.Nix.Store.Remote.Types (
68
MonadStore
9+
, MonadStoreT(..)
710
, StoreConfig(..)
811
, Logger(..)
912
, Field(..)
@@ -20,16 +23,33 @@ module System.Nix.Store.Remote.Types (
2023
import Data.ByteString (ByteString)
2124
import qualified Data.ByteString.Lazy as BSL
2225
import Network.Socket (Socket)
26+
import Control.Applicative (Alternative)
2327
import Control.Monad.Except
2428
import Control.Monad.Reader
2529
import Control.Monad.State
30+
import Control.Monad.Fail ( MonadFail )
2631

2732
data StoreConfig = StoreConfig {
2833
storeDir :: FilePath
2934
, storeSocket :: Socket
3035
}
3136

32-
type MonadStore a = ExceptT String (StateT (Maybe BSL.ByteString, [Logger]) (ReaderT StoreConfig IO)) a
37+
newtype MonadStoreT m a = NixStore {
38+
unStore :: ExceptT String (StateT (Maybe BSL.ByteString, [Logger]) (ReaderT StoreConfig m)) a
39+
} deriving
40+
( Functor
41+
, Applicative
42+
, Alternative
43+
, Monad
44+
, MonadFail
45+
, MonadError String
46+
, MonadIO
47+
)
48+
49+
instance MonadTrans MonadStoreT where
50+
lift = NixStore . lift . lift . lift
51+
52+
type MonadStore a = MonadStoreT IO a
3353

3454
type ActivityID = Int
3555
type ActivityParentID = Int
@@ -55,23 +75,23 @@ isError :: Logger -> Bool
5575
isError (Error _ _) = True
5676
isError _ = False
5777

58-
gotError :: MonadStore Bool
59-
gotError = any isError . snd <$> get
78+
gotError :: (MonadIO m) => MonadStoreT m Bool
79+
gotError = any isError . snd <$> NixStore get
6080

61-
getError :: MonadStore [Logger]
62-
getError = filter isError . snd <$> get
81+
getError :: (MonadIO m) => MonadStoreT m [Logger]
82+
getError = filter isError . snd <$> NixStore get
6383

64-
getLog :: MonadStore [Logger]
65-
getLog = snd <$> get
84+
getLog :: (MonadIO m) => MonadStoreT m [Logger]
85+
getLog = snd <$> NixStore get
6686

67-
flushLog :: MonadStore ()
68-
flushLog = modify (\(a, _b) -> (a, []))
87+
flushLog :: (MonadIO m) => MonadStoreT m ()
88+
flushLog = NixStore $ modify (\(a, _b) -> (a, []))
6989

70-
setData :: BSL.ByteString -> MonadStore ()
71-
setData x = modify (\(_, b) -> (Just x, b))
90+
setData :: (MonadIO m) => BSL.ByteString -> MonadStoreT m ()
91+
setData x = NixStore $ modify (\(_, b) -> (Just x, b))
7292

73-
clearData :: MonadStore ()
74-
clearData = modify (\(_, b) -> (Nothing, b))
93+
clearData :: (MonadIO m) => MonadStoreT m ()
94+
clearData = NixStore $ modify (\(_, b) -> (Nothing, b))
7595

76-
getStoreDir :: MonadStore FilePath
77-
getStoreDir = storeDir <$> ask
96+
getStoreDir :: (MonadIO m) => MonadStoreT m FilePath
97+
getStoreDir = storeDir <$> NixStore ask

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,51 +41,51 @@ genericIncremental getsome parser = go decoder
4141
go (Fail _leftover _consumed msg) = do
4242
error msg
4343

44-
getSocketIncremental :: Get a -> MonadStore a
44+
getSocketIncremental :: (MonadIO m) => Get a -> MonadStoreT m a
4545
getSocketIncremental = genericIncremental sockGet8
4646
where
47-
sockGet8 :: MonadStore (Maybe BSC.ByteString)
47+
sockGet8 :: (MonadIO m) => MonadStoreT m (Maybe BSC.ByteString)
4848
sockGet8 = do
49-
soc <- storeSocket <$> ask
49+
soc <- storeSocket <$> NixStore ask
5050
liftIO $ Just <$> recv soc 8
5151

52-
sockPut :: Put -> MonadStore ()
52+
sockPut :: (MonadIO m) => Put -> MonadStoreT m ()
5353
sockPut p = do
54-
soc <- storeSocket <$> ask
54+
soc <- storeSocket <$> NixStore ask
5555
liftIO $ sendAll soc $ BSL.toStrict $ runPut p
5656

57-
sockGet :: Get a -> MonadStore a
57+
sockGet :: (MonadIO m) => Get a -> MonadStoreT m a
5858
sockGet = getSocketIncremental
5959

60-
sockGetInt :: Integral a => MonadStore a
60+
sockGetInt :: (MonadIO m) => Integral a => MonadStoreT m a
6161
sockGetInt = getSocketIncremental getInt
6262

63-
sockGetBool :: MonadStore Bool
63+
sockGetBool :: (MonadIO m) => MonadStoreT m Bool
6464
sockGetBool = (== (1 :: Int)) <$> sockGetInt
6565

66-
sockGetStr :: MonadStore ByteString
66+
sockGetStr :: (MonadIO m) => MonadStoreT m ByteString
6767
sockGetStr = getSocketIncremental getByteStringLen
6868

69-
sockGetStrings :: MonadStore [ByteString]
69+
sockGetStrings :: (MonadIO m) => MonadStoreT m [ByteString]
7070
sockGetStrings = getSocketIncremental getByteStrings
7171

72-
sockGetPath :: MonadStore StorePath
72+
sockGetPath :: (MonadIO m) => MonadStoreT m StorePath
7373
sockGetPath = do
7474
sd <- getStoreDir
7575
pth <- getSocketIncremental (getPath sd)
7676
case pth of
7777
Left e -> throwError e
7878
Right x -> return x
7979

80-
sockGetPathMay :: MonadStore (Maybe StorePath)
80+
sockGetPathMay :: (MonadIO m) => MonadStoreT m (Maybe StorePath)
8181
sockGetPathMay = do
8282
sd <- getStoreDir
8383
pth <- getSocketIncremental (getPath sd)
8484
return $ case pth of
8585
Left _e -> Nothing
8686
Right x -> Just x
8787

88-
sockGetPaths :: MonadStore StorePathSet
88+
sockGetPaths :: (MonadIO m) => MonadStoreT m StorePathSet
8989
sockGetPaths = do
9090
sd <- getStoreDir
9191
getSocketIncremental (getPaths sd)

0 commit comments

Comments
 (0)