aboutsummaryrefslogtreecommitdiff
path: root/server/src/Thermoprint/Server/QMConfig.hs
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/Thermoprint/Server/QMConfig.hs')
-rw-r--r--server/src/Thermoprint/Server/QMConfig.hs129
1 files changed, 0 insertions, 129 deletions
diff --git a/server/src/Thermoprint/Server/QMConfig.hs b/server/src/Thermoprint/Server/QMConfig.hs
deleted file mode 100644
index 7255c8c..0000000
--- a/server/src/Thermoprint/Server/QMConfig.hs
+++ /dev/null
@@ -1,129 +0,0 @@
1{-# LANGUAGE GADTs #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE ImpredicativeTypes #-}
4{-# LANGUAGE TypeOperators #-}
5{-# LANGUAGE RecordWildCards #-}
6{-# LANGUAGE ViewPatterns #-}
7{-# LANGUAGE ConstraintKinds #-}
8{-# LANGUAGE MultiParamTypeClasses #-}
9{-# LANGUAGE KindSignatures #-}
10{-# LANGUAGE FlexibleInstances #-}
11{-# LANGUAGE UndecidableInstances #-}
12{-# LANGUAGE IncoherentInstances #-}
13
14module Thermoprint.Server.QMConfig
15 ( QMConfig(..)
16 , nullQM
17 , idQM
18 , standardSleep
19 , limitHistorySize
20 , limitHistoryAge
21 ) where
22
23import Control.Monad.Trans.Resource
24import Control.Monad.Trans.Control
25import Control.Monad.Trans.Identity
26import Control.Monad.Logger
27import Control.Monad.Reader
28import Control.Monad.IO.Class
29import Control.Monad.Morph
30import Control.Monad.Trans.Compose
31import Control.Monad.State
32import Control.Category
33import Servant.Server.Internal.Enter
34
35import Data.Constraint
36import Data.Constraint.Forall
37
38import Data.Default.Class
39
40import Data.Sequence (Seq)
41import qualified Data.Sequence as Seq
42import Data.Time
43import Data.Foldable
44
45import Control.Concurrent.STM
46
47import Thermoprint.Server.Queue hiding (idQM, intersection, nullQM, union, runQM)
48import qualified Thermoprint.Server.Queue as Q
49
50import Thermoprint.Server.Database (JobId)
51
52import Prelude hiding (length, maximum, id, (.))
53
54type QMTrans t = ( MonadTrans t
55 , MFunctor t
56 , Monad (t STM)
57 , MonadIO (t IO)
58 , Monad (QueueManagerM t)
59 , MonadState Queue (QueueManagerM t)
60 )
61
62class QMTrans1 (t :: (* -> *) -> * -> *) (t' :: (* -> *) -> * -> *)
63instance QMTrans (ComposeT t t') => QMTrans1 t t'
64
65type QMTrans' t = (QMTrans t, Forall (QMTrans1 t))
66
67data QMConfig where
68 QMConfig :: QMTrans' t => QueueManager t -> (forall m. (t m) :~> m) -> QMConfig
69 QMConfig' :: ( forall t . QMTrans' t => QueueManager t
70 ) -> QMConfig
71
72instance Default QMConfig where
73 def = idQM
74
75intersection :: Foldable f => f QMConfig -> QMConfig
76intersection = foldr' (qmCombine Q.intersection) idQM
77
78idQM :: QMConfig
79idQM = QMConfig' Q.idQM
80
81union :: Foldable f => f QMConfig -> QMConfig
82union = foldr' (qmCombine Q.union) idQM
83
84nullQM :: QMConfig
85nullQM = QMConfig' Q.nullQM
86
87qmCombine :: (forall f t. (Foldable f, MonadState Queue (QueueManagerM t)) => f (QueueManager t) -> QueueManager t) -> QMConfig -> QMConfig -> QMConfig
88qmCombine qmCombine' (QMConfig a natA) (QMConfig b natB) = (QMConfig (qmCombine' [a', b']) (natComp natA natB)) \\ (inst :: Forall (QMTrans1 t) :- QMTrans (ComposeT t t'))
89 where
90 a' = mapComposeT (hoist $ ComposeT . hoist lift) a
91 b' = mapComposeT (hoist $ ComposeT . lift) b
92
93natComp :: (forall m. t m :~> m)
94 -> (forall m. t' m :~> m)
95 -> (forall m. (MFunctor t
96 , Monad (t' m)
97 ) => ComposeT t t' m :~> m
98 )
99natComp natA natB = natA . hoistNat natB . Nat getComposeT
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
104
105standardSleep :: Monad (QueueManagerM t) => QueueManager t
106-- ^ Instruct 'runQM' to sleep some standard amount of time
107--
108-- /TODO/: Investigate implementing a smarter algorithm (PID-controller)
109standardSleep = return $ 20
110
111limitHistorySize :: Int -> QMConfig
112-- ^ Limit a 'Queue's 'history's size to some number of 'QueueEntry's
113limitHistorySize max = QMConfig' $ modify' limitSize >> standardSleep
114 where
115 limitSize :: Queue -> Queue
116 limitSize q@Queue{..} = q { history = Seq.take max history }
117
118limitHistoryAge :: NominalDiffTime -- ^ Maximum age relative to the youngest 'QueueEntry'
119 -> QMConfig
120-- ^ Limit a 'Queue's 'history's contents to 'QueueEntry's below a certain age
121limitHistoryAge maxAge = QMConfig' $ modify' limitAge >> standardSleep
122 where
123 limitAge :: Queue -> Queue
124 limitAge q@Queue{..} = q { history = Seq.filter (filterAge . created . fst) history}
125 where
126 youngest :: UTCTime
127 youngest = maximum $ created . fst <$> history
128 filterAge :: UTCTime -> Bool
129 filterAge time = not $ (youngest `diffUTCTime` time) > maxAge