Skip to content

Commit 087ec38

Browse files
committed
Lift the monad stack to a monad stack transformer
1 parent 8508b9f commit 087ec38

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
, addTextToStore
1416
, addSignatures
1517
, addIndirectRoot
@@ -37,6 +39,7 @@ module System.Nix.Store.Remote
3739
where
3840

3941
import Control.Monad (void, unless, when)
42+
import Control.Monad.IO.Class (MonadIO)
4043
import Data.ByteString.Lazy (ByteString)
4144
import Data.Map.Strict (Map)
4245
import Data.Text (Text)
@@ -72,13 +75,13 @@ type CheckSigsFlag = Bool
7275
type SubstituteFlag = Bool
7376

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

8487
runOpArgsIO AddToStore $ \yield -> do
@@ -101,11 +104,12 @@ addToStore name pth recursive _pathFilter _repair = do
101104
--
102105
-- Reference accepts repair but only uses it
103106
-- to throw error in case of remote talking to nix-daemon.
104-
addTextToStore :: Text -- ^ Name of the text
107+
addTextToStore :: (MonadIO m)
108+
=> Text -- ^ Name of the text
105109
-> Text -- ^ Actual text to add
106110
-> StorePathSet -- ^ Set of `StorePath`s that the added text references
107111
-> RepairFlag -- ^ Repair flag, must be `False` in case of remote backend
108-
-> MonadStore StorePath
112+
-> MonadStoreT m StorePath
109113
addTextToStore name text references' repair = do
110114
when repair $ error "repairing is not supported when building through the Nix daemon"
111115
runOpArgs AddTextToStore $ do
@@ -156,7 +160,7 @@ buildDerivation p drv buildMode = do
156160
-- XXX: reason for this is unknown
157161
-- but without it protocol just hangs waiting for
158162
-- more data. Needs investigation
159-
putInt 0
163+
putInt (0 :: Int)
160164

161165
res <- getSocketIncremental $ getBuildResult
162166
return res
@@ -172,7 +176,7 @@ findRoots = do
172176
sd <- getStoreDir
173177
res <- getSocketIncremental
174178
$ getMany
175-
$ (,) <$> (Data.ByteString.Lazy.fromStrict <$> getByteStringLen)
179+
$ (,) <$> (Data.ByteString.Lazy.fromStrict <$> getByteStringLen)
176180
<*> getPath sd
177181

178182
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
@@ -15,6 +16,7 @@ import Control.Exception (bracket)
1516
import Control.Monad.Except
1617
import Control.Monad.Reader
1718
import Control.Monad.State
19+
import Control.Monad.Trans.Control (MonadBaseControl, liftBaseOp)
1820

1921
import Data.Binary.Get
2022
import Data.Binary.Put
@@ -114,25 +116,27 @@ opNum AddToStoreNar = 39
114116
opNum QueryMissing = 40
115117

116118

117-
simpleOp :: WorkerOp -> MonadStore Bool
119+
simpleOp :: (MonadIO m) => WorkerOp -> MonadStoreT m Bool
118120
simpleOp op = do
119121
simpleOpArgs op $ return ()
120122

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

132-
runOp :: WorkerOp -> MonadStore ()
136+
runOp :: (MonadIO m) => WorkerOp -> MonadStoreT m ()
133137
runOp op = runOpArgs op $ return ()
134138

135-
runOpArgs :: WorkerOp -> Put -> MonadStore ()
139+
runOpArgs :: (MonadIO m) => WorkerOp -> Put -> MonadStoreT m ()
136140
runOpArgs op args = runOpArgsIO op (\encode -> encode $ Data.ByteString.Lazy.toStrict $ runPut args)
137141

138142
runOpArgsIO :: WorkerOp -> ((Data.ByteString.ByteString -> MonadStore ()) -> MonadStore ()) -> MonadStore ()
@@ -145,18 +149,21 @@ runOpArgsIO op encoder = do
145149
encoder (liftIO . sendAll soc)
146150

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

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

157-
runStoreOpts :: FilePath -> FilePath -> MonadStore a -> IO (Either String a, [Logger])
164+
runStoreOpts :: (MonadIO m, MonadBaseControl IO m) => FilePath -> FilePath -> MonadStoreT m a -> m (Either String a, [Logger])
158165
runStoreOpts sockPath storeRootDir code = do
159-
bracket (open sockPath) (Network.Socket.close . storeSocket) run
166+
liftBaseOp (bracket (open sockPath) (Network.Socket.close . storeSocket)) run
160167
where
161168
open path = do
162169
soc <-
@@ -169,9 +176,10 @@ runStoreOpts sockPath storeRootDir code = do
169176
return $ StoreConfig { storeSocket = soc
170177
, storeDir = storeRootDir }
171178

179+
greet :: MonadIO m => MonadStoreT m [Logger]
172180
greet = do
173181
sockPut $ putInt workerMagic1
174-
soc <- storeSocket <$> ask
182+
soc <- storeSocket <$> NixStore ask
175183
vermagic <- liftIO $ recv soc 16
176184
let (magic2, _daemonProtoVersion) =
177185
flip runGet (Data.ByteString.Lazy.fromStrict vermagic)
@@ -189,4 +197,5 @@ runStoreOpts sockPath storeRootDir code = do
189197
fmap (\(res, (_data, logs)) -> (res, logs))
190198
$ flip runReaderT sock
191199
$ flip runStateT (Nothing, [])
192-
$ runExceptT (greet >> code)
200+
$ runExceptT
201+
$ 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
@@ -44,51 +44,51 @@ genericIncremental getsome parser = go decoder
4444
go (Fail _leftover _consumed msg) = do
4545
error msg
4646

47-
getSocketIncremental :: Get a -> MonadStore a
47+
getSocketIncremental :: (MonadIO m) => Get a -> MonadStoreT m a
4848
getSocketIncremental = genericIncremental sockGet8
4949
where
50-
sockGet8 :: MonadStore (Maybe BSC.ByteString)
50+
sockGet8 :: (MonadIO m) => MonadStoreT m (Maybe BSC.ByteString)
5151
sockGet8 = do
52-
soc <- storeSocket <$> ask
52+
soc <- storeSocket <$> NixStore ask
5353
liftIO $ Just <$> recv soc 8
5454

55-
sockPut :: Put -> MonadStore ()
55+
sockPut :: (MonadIO m) => Put -> MonadStoreT m ()
5656
sockPut p = do
57-
soc <- storeSocket <$> ask
57+
soc <- storeSocket <$> NixStore ask
5858
liftIO $ sendAll soc $ BSL.toStrict $ runPut p
5959

60-
sockGet :: Get a -> MonadStore a
60+
sockGet :: (MonadIO m) => Get a -> MonadStoreT m a
6161
sockGet = getSocketIncremental
6262

63-
sockGetInt :: Integral a => MonadStore a
63+
sockGetInt :: (MonadIO m) => Integral a => MonadStoreT m a
6464
sockGetInt = getSocketIncremental getInt
6565

66-
sockGetBool :: MonadStore Bool
66+
sockGetBool :: (MonadIO m) => MonadStoreT m Bool
6767
sockGetBool = (== (1 :: Int)) <$> sockGetInt
6868

69-
sockGetStr :: MonadStore ByteString
69+
sockGetStr :: (MonadIO m) => MonadStoreT m ByteString
7070
sockGetStr = getSocketIncremental getByteStringLen
7171

72-
sockGetStrings :: MonadStore [ByteString]
72+
sockGetStrings :: (MonadIO m) => MonadStoreT m [ByteString]
7373
sockGetStrings = getSocketIncremental getByteStrings
7474

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

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

91-
sockGetPaths :: MonadStore StorePathSet
91+
sockGetPaths :: (MonadIO m) => MonadStoreT m StorePathSet
9292
sockGetPaths = do
9393
sd <- getStoreDir
9494
getSocketIncremental (getPaths sd)

0 commit comments

Comments
 (0)