aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2016-02-29 22:14:57 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2016-02-29 22:14:57 +0100
commitd07c1cf5d04f802501a98ce986b78d42b7329901 (patch)
treefeac0da36aed47723c3a7b75ad9df24eb5103007
parent844f5e96097f8fcced94220487a7c5ad40c1e97f (diff)
downloadthermoprint-d07c1cf5d04f802501a98ce986b78d42b7329901.tar
thermoprint-d07c1cf5d04f802501a98ce986b78d42b7329901.tar.gz
thermoprint-d07c1cf5d04f802501a98ce986b78d42b7329901.tar.bz2
thermoprint-d07c1cf5d04f802501a98ce986b78d42b7329901.tar.xz
thermoprint-d07c1cf5d04f802501a98ce986b78d42b7329901.zip
Further work on QMConfig tools
-rw-r--r--server/src/Thermoprint/Server.hs6
-rw-r--r--server/src/Thermoprint/Server/QMConfig.hs92
-rw-r--r--server/thermoprint-server.cabal1
-rw-r--r--server/thermoprint-server.nix19
4 files changed, 69 insertions, 49 deletions
diff --git a/server/src/Thermoprint/Server.hs b/server/src/Thermoprint/Server.hs
index 49f3e82..c2a4972 100644
--- a/server/src/Thermoprint/Server.hs
+++ b/server/src/Thermoprint/Server.hs
@@ -89,7 +89,7 @@ import Debug.Trace
89data Config m = Config { dyreError :: Maybe String -- ^ Set by 'Dyre' -- sent to log as an error 89data Config m = Config { dyreError :: Maybe String -- ^ Set by 'Dyre' -- sent to log as an error
90 , warpSettings :: Warp.Settings -- ^ Configure 'Warp's behaviour 90 , warpSettings :: Warp.Settings -- ^ Configure 'Warp's behaviour
91 , printers :: Map API.PrinterId Printer 91 , printers :: Map API.PrinterId Printer
92 , queueManagers :: API.PrinterId -> QMConfig m 92 , queueManagers :: API.PrinterId -> QMConfig
93 } 93 }
94 94
95instance MonadIO m => Default (Config m) where 95instance MonadIO m => Default (Config m) where
@@ -99,7 +99,7 @@ instance MonadIO m => Default (Config m) where
99 , queueManagers = const def 99 , queueManagers = const def
100 } 100 }
101 101
102withPrinters :: MonadResource m => Config m -> [(m PrinterMethod, QMConfig m)] -> m (Config m) 102withPrinters :: MonadResource m => Config m -> [(m PrinterMethod, QMConfig)] -> m (Config m)
103-- ^ Add a list of printers to a 'Config' 103-- ^ Add a list of printers to a 'Config'
104withPrinters cfg = fmap updateCfg . foldlM mapInsert (Map.mapWithKey (\k a -> (a, queueManagers cfg k)) $ printers cfg) 104withPrinters cfg = fmap updateCfg . foldlM mapInsert (Map.mapWithKey (\k a -> (a, queueManagers cfg k)) $ printers cfg)
105 where 105 where
@@ -140,7 +140,7 @@ thermoprintServer dyre io = Dyre.wrapMain $ Dyre.defaultParams
140 gcChan <- liftIO newTChanIO 140 gcChan <- liftIO newTChanIO
141 fork tMgr $ jobGC gcChan 141 fork tMgr $ jobGC gcChan
142 let 142 let
143 runQM' = runQM gcChan . queueManagers 143 runQM' = liftIO . runQM gcChan . queueManagers
144 mapM_ (fork tMgr . uncurry runQM') $ Map.toList printers 144 mapM_ (fork tMgr . uncurry runQM') $ Map.toList printers
145 nChan <- liftIO $ newBroadcastTChanIO 145 nChan <- liftIO $ newBroadcastTChanIO
146 let 146 let
diff --git a/server/src/Thermoprint/Server/QMConfig.hs b/server/src/Thermoprint/Server/QMConfig.hs
index 8f08faf..7255c8c 100644
--- a/server/src/Thermoprint/Server/QMConfig.hs
+++ b/server/src/Thermoprint/Server/QMConfig.hs
@@ -4,6 +4,12 @@
4{-# LANGUAGE TypeOperators #-} 4{-# LANGUAGE TypeOperators #-}
5{-# LANGUAGE RecordWildCards #-} 5{-# LANGUAGE RecordWildCards #-}
6{-# LANGUAGE ViewPatterns #-} 6{-# LANGUAGE ViewPatterns #-}
7{-# LANGUAGE ConstraintKinds #-}
8{-# LANGUAGE MultiParamTypeClasses #-}
9{-# LANGUAGE KindSignatures #-}
10{-# LANGUAGE FlexibleInstances #-}
11{-# LANGUAGE UndecidableInstances #-}
12{-# LANGUAGE IncoherentInstances #-}
7 13
8module Thermoprint.Server.QMConfig 14module Thermoprint.Server.QMConfig
9 ( QMConfig(..) 15 ( QMConfig(..)
@@ -21,9 +27,13 @@ import Control.Monad.Logger
21import Control.Monad.Reader 27import Control.Monad.Reader
22import Control.Monad.IO.Class 28import Control.Monad.IO.Class
23import Control.Monad.Morph 29import Control.Monad.Morph
30import Control.Monad.Trans.Compose
24import Control.Monad.State 31import Control.Monad.State
25import Control.Category 32import Control.Category
26import Servant.Server.Internal.Enter (enter, (:~>)(..)) 33import Servant.Server.Internal.Enter
34
35import Data.Constraint
36import Data.Constraint.Forall
27 37
28import Data.Default.Class 38import Data.Default.Class
29 39
@@ -37,52 +47,60 @@ import Control.Concurrent.STM
37import Thermoprint.Server.Queue hiding (idQM, intersection, nullQM, union, runQM) 47import Thermoprint.Server.Queue hiding (idQM, intersection, nullQM, union, runQM)
38import qualified Thermoprint.Server.Queue as Q 48import qualified Thermoprint.Server.Queue as Q
39 49
50import Thermoprint.Server.Database (JobId)
51
40import Prelude hiding (length, maximum, id, (.)) 52import Prelude hiding (length, maximum, id, (.))
41 53
42data QMConfig m where 54type QMTrans t = ( MonadTrans t
43 QMConfig :: ( MonadTrans t 55 , MFunctor t
44 , MFunctor t 56 , Monad (t STM)
45 , Monad (t STM) 57 , MonadIO (t IO)
46 , MonadIO (t IO) 58 , Monad (QueueManagerM t)
47 ) => QueueManager t -> (t IO) :~> m -> QMConfig m 59 , MonadState Queue (QueueManagerM t)
48 QMConfig' :: ( MonadIO m 60 )
49 ) => ( forall t. ( MonadTrans t 61
50 , MFunctor t 62class QMTrans1 (t :: (* -> *) -> * -> *) (t' :: (* -> *) -> * -> *)
51 , Monad (t STM) 63instance QMTrans (ComposeT t t') => QMTrans1 t t'
52 , MonadIO (t IO) 64
53 , Monad (QueueManagerM t) 65type QMTrans' t = (QMTrans t, Forall (QMTrans1 t))
54 ) => QueueManager t 66
55 ) -> QMConfig m 67data QMConfig where
56 68 QMConfig :: QMTrans' t => QueueManager t -> (forall m. (t m) :~> m) -> QMConfig
57instance MonadIO m => Default (QMConfig m) where 69 QMConfig' :: ( forall t . QMTrans' t => QueueManager t
70 ) -> QMConfig
71
72instance Default QMConfig where
58 def = idQM 73 def = idQM
59 74
60intersection :: (Functor f, Foldable f, MonadIO m) => f (QMConfig m) -> QMConfig m 75intersection :: Foldable f => f QMConfig -> QMConfig
61intersection = foldr' (qmCombine Q.intersection) idQM 76intersection = foldr' (qmCombine Q.intersection) idQM
62 77
63idQM :: MonadIO m => QMConfig m 78idQM :: QMConfig
64idQM = QMConfig' Q.idQM 79idQM = QMConfig' Q.idQM
65 80
66union :: (Foldable f, MonadIO m) => f (QMConfig m) -> QMConfig m 81union :: Foldable f => f QMConfig -> QMConfig
67union = foldr' (qmCombine Q.union) idQM 82union = foldr' (qmCombine Q.union) idQM
68 83
69nullQM :: MonadIO m => QMConfig m 84nullQM :: QMConfig
70nullQM = QMConfig' Q.nullQM 85nullQM = QMConfig' Q.nullQM
71 86
72qmCombine :: ([QueueManager t] -> QueueManager t) -> QMConfig m -> QMConfig m -> QMConfig m 87qmCombine :: (forall f t. (Foldable f, MonadState Queue (QueueManagerM t)) => f (QueueManager t) -> QueueManager t) -> QMConfig -> QMConfig -> QMConfig
73qmCombine qmCombine' (QMConfig a natA) (QMConfig b natB) = undefined 88qmCombine qmCombine' (QMConfig a natA) (QMConfig b natB) = (QMConfig (qmCombine' [a', b']) (natComp natA natB)) \\ (inst :: Forall (QMTrans1 t) :- QMTrans (ComposeT t t'))
74 where 89 where
75 natA :: t IO :~> m 90 a' = mapComposeT (hoist $ ComposeT . hoist lift) a
76 natB :: t' IO :~> m 91 b' = mapComposeT (hoist $ ComposeT . lift) b
77 --- 92
78 hoistNat natB :: t (t' IO) :~> t m 93natComp :: (forall m. t m :~> m)
79 -- 94 -> (forall m. t' m :~> m)
80 ? :: t m :~> m 95 -> (forall m. (MFunctor t
81 natAB :: ComposeT t t' IO :~> m 96 , Monad (t' m)
82 97 ) => ComposeT t t' m :~> m
83runQM :: ( HasQueue q ) => TChan JobId -> QMConfig m -> q -> t IO () 98 )
84runQM gcChan (QMConfig qm nat) q = unNat nat $ runQM gcChan qm q 99natComp natA natB = natA . hoistNat natB . Nat getComposeT
85runQM gcChan (QMConfig' qm) q = hoist liftIO $ runQM gcChan qm q 100
101runQM :: ( HasQueue q ) => TChan JobId -> QMConfig -> q -> IO ()
102runQM gcChan (QMConfig qm nat) q = unNat nat $ Q.runQM gcChan qm q
103runQM gcChan (QMConfig' qm) q = runIdentityT $ Q.runQM gcChan qm q
86 104
87standardSleep :: Monad (QueueManagerM t) => QueueManager t 105standardSleep :: Monad (QueueManagerM t) => QueueManager t
88-- ^ Instruct 'runQM' to sleep some standard amount of time 106-- ^ Instruct 'runQM' to sleep some standard amount of time
@@ -90,15 +108,15 @@ standardSleep :: Monad (QueueManagerM t) => QueueManager t
90-- /TODO/: Investigate implementing a smarter algorithm (PID-controller) 108-- /TODO/: Investigate implementing a smarter algorithm (PID-controller)
91standardSleep = return $ 20 109standardSleep = return $ 20
92 110
93limitHistorySize :: MonadIO m => Int -> QMConfig m 111limitHistorySize :: Int -> QMConfig
94-- ^ Limit a 'Queue's 'history's size to some number of 'QueueEntry's 112-- ^ Limit a 'Queue's 'history's size to some number of 'QueueEntry's
95limitHistorySize max = QMConfig' $ modify' limitSize >> standardSleep 113limitHistorySize max = QMConfig' $ modify' limitSize >> standardSleep
96 where 114 where
97 limitSize :: Queue -> Queue 115 limitSize :: Queue -> Queue
98 limitSize q@Queue{..} = q { history = Seq.take max history } 116 limitSize q@Queue{..} = q { history = Seq.take max history }
99 117
100limitHistoryAge :: MonadIO m => NominalDiffTime -- ^ Maximum age relative to the youngest 'QueueEntry' 118limitHistoryAge :: NominalDiffTime -- ^ Maximum age relative to the youngest 'QueueEntry'
101 -> QMConfig m 119 -> QMConfig
102-- ^ Limit a 'Queue's 'history's contents to 'QueueEntry's below a certain age 120-- ^ Limit a 'Queue's 'history's contents to 'QueueEntry's below a certain age
103limitHistoryAge maxAge = QMConfig' $ modify' limitAge >> standardSleep 121limitHistoryAge maxAge = QMConfig' $ modify' limitAge >> standardSleep
104 where 122 where
diff --git a/server/thermoprint-server.cabal b/server/thermoprint-server.cabal
index 2fa04c5..0a5690e 100644
--- a/server/thermoprint-server.cabal
+++ b/server/thermoprint-server.cabal
@@ -66,6 +66,7 @@ library
66 , wai-websockets >=3.0.0 && <4 66 , wai-websockets >=3.0.0 && <4
67 , wai >=3.0.5 && <4 67 , wai >=3.0.5 && <4
68 , network-uri >=2.6.0 && <3 68 , network-uri >=2.6.0 && <3
69 , constraints >=0.8 && <1
69 hs-source-dirs: src 70 hs-source-dirs: src
70 default-language: Haskell2010 71 default-language: Haskell2010
71 ghc-options: -Wall 72 ghc-options: -Wall
diff --git a/server/thermoprint-server.nix b/server/thermoprint-server.nix
index 6ff8b10..ff8ebd4 100644
--- a/server/thermoprint-server.nix
+++ b/server/thermoprint-server.nix
@@ -1,7 +1,7 @@
1{ mkDerivation, async, base, binary, bytestring, conduit 1{ mkDerivation, async, base, binary, bytestring, conduit
2, containers, data-default-class, deepseq, dyre, either, encoding 2, constraints, containers, data-default-class, deepseq, dyre
3, exceptions, extended-reals, filelock, hspec, mmorph 3, either, encoding, exceptions, extended-reals, filelock, hspec
4, monad-control, monad-logger, mtl, network-uri, persistent 4, mmorph, monad-control, monad-logger, mtl, network-uri, persistent
5, persistent-sqlite, persistent-template, QuickCheck 5, persistent-sqlite, persistent-template, QuickCheck
6, quickcheck-instances, resourcet, servant, servant-server, stdenv 6, quickcheck-instances, resourcet, servant, servant-server, stdenv
7, stm, temporary, text, thermoprint-client, thermoprint-spec, time 7, stm, temporary, text, thermoprint-client, thermoprint-spec, time
@@ -14,12 +14,13 @@ mkDerivation {
14 isLibrary = true; 14 isLibrary = true;
15 isExecutable = true; 15 isExecutable = true;
16 libraryHaskellDepends = [ 16 libraryHaskellDepends = [
17 base binary bytestring conduit containers data-default-class 17 base binary bytestring conduit constraints containers
18 deepseq dyre either encoding exceptions extended-reals filelock 18 data-default-class deepseq dyre either encoding exceptions
19 mmorph monad-control monad-logger mtl network-uri persistent 19 extended-reals filelock mmorph monad-control monad-logger mtl
20 persistent-template QuickCheck quickcheck-instances resourcet 20 network-uri persistent persistent-template QuickCheck
21 servant servant-server stm text thermoprint-spec time transformers 21 quickcheck-instances resourcet servant servant-server stm text
22 wai wai-websockets warp websockets 22 thermoprint-spec time transformers wai wai-websockets warp
23 websockets
23 ]; 24 ];
24 executableHaskellDepends = [ 25 executableHaskellDepends = [
25 base monad-logger mtl persistent-sqlite resourcet 26 base monad-logger mtl persistent-sqlite resourcet