diff options
author | Gregor Kleen <gkleen@yggdrasil.li> | 2016-02-29 22:18:53 +0100 |
---|---|---|
committer | Gregor Kleen <gkleen@yggdrasil.li> | 2016-02-29 22:18:53 +0100 |
commit | 8dc71c2a4219f2e820e4c55ee7754e184574e8e5 (patch) | |
tree | 6bd515672187832da6dbbaaf49626be526b3be93 /server | |
parent | d07c1cf5d04f802501a98ce986b78d42b7329901 (diff) | |
download | thermoprint-8dc71c2a4219f2e820e4c55ee7754e184574e8e5.tar thermoprint-8dc71c2a4219f2e820e4c55ee7754e184574e8e5.tar.gz thermoprint-8dc71c2a4219f2e820e4c55ee7754e184574e8e5.tar.bz2 thermoprint-8dc71c2a4219f2e820e4c55ee7754e184574e8e5.tar.xz thermoprint-8dc71c2a4219f2e820e4c55ee7754e184574e8e5.zip |
Revert work on QMConfig & associated tools
This reverts commit f64e26726ce5468069093aa86fe973ad4be4816c.
Diffstat (limited to 'server')
-rw-r--r-- | server/src/Thermoprint/Server.hs | 24 | ||||
-rw-r--r-- | server/src/Thermoprint/Server/QMConfig.hs | 129 | ||||
-rw-r--r-- | server/test/Thermoprint/ServerSpec.hs | 3 | ||||
-rw-r--r-- | server/thermoprint-server.cabal | 2 | ||||
-rw-r--r-- | server/thermoprint-server.nix | 19 |
5 files changed, 27 insertions, 150 deletions
diff --git a/server/src/Thermoprint/Server.hs b/server/src/Thermoprint/Server.hs index c2a4972..446c63e 100644 --- a/server/src/Thermoprint/Server.hs +++ b/server/src/Thermoprint/Server.hs | |||
@@ -4,6 +4,7 @@ | |||
4 | {-# LANGUAGE TypeOperators #-} | 4 | {-# LANGUAGE TypeOperators #-} |
5 | {-# LANGUAGE FlexibleContexts #-} | 5 | {-# LANGUAGE FlexibleContexts #-} |
6 | {-# LANGUAGE ImpredicativeTypes #-} | 6 | {-# LANGUAGE ImpredicativeTypes #-} |
7 | {-# LANGUAGE ExistentialQuantification #-} | ||
7 | {-# LANGUAGE ViewPatterns #-} | 8 | {-# LANGUAGE ViewPatterns #-} |
8 | {-# LANGUAGE DataKinds #-} | 9 | {-# LANGUAGE DataKinds #-} |
9 | 10 | ||
@@ -14,8 +15,7 @@ module Thermoprint.Server | |||
14 | , module Data.Default.Class | 15 | , module Data.Default.Class |
15 | , module Servant.Server.Internal.Enter | 16 | , module Servant.Server.Internal.Enter |
16 | , module Thermoprint.Server.Printer | 17 | , module Thermoprint.Server.Printer |
17 | , module Thermoprint.Server.QMConfig | 18 | , module Thermoprint.Server.Queue |
18 | , Queue(..), QueueEntry(..) | ||
19 | ) where | 19 | ) where |
20 | 20 | ||
21 | import Data.Default.Class | 21 | import Data.Default.Class |
@@ -78,8 +78,7 @@ import Thermoprint.Server.Push | |||
78 | 78 | ||
79 | import Thermoprint.Server.Database | 79 | import Thermoprint.Server.Database |
80 | import Thermoprint.Server.Printer | 80 | import Thermoprint.Server.Printer |
81 | import Thermoprint.Server.Queue hiding (intersection, idQM, union, nullQM, runQM) | 81 | import Thermoprint.Server.Queue |
82 | import Thermoprint.Server.QMConfig | ||
83 | import qualified Thermoprint.Server.API as API (thermoprintServer) | 82 | import qualified Thermoprint.Server.API as API (thermoprintServer) |
84 | import Thermoprint.Server.API hiding (thermoprintServer) | 83 | import Thermoprint.Server.API hiding (thermoprintServer) |
85 | 84 | ||
@@ -89,9 +88,17 @@ import Debug.Trace | |||
89 | data Config m = Config { dyreError :: Maybe String -- ^ Set by 'Dyre' -- sent to log as an error | 88 | data Config m = Config { dyreError :: Maybe String -- ^ Set by 'Dyre' -- sent to log as an error |
90 | , warpSettings :: Warp.Settings -- ^ Configure 'Warp's behaviour | 89 | , warpSettings :: Warp.Settings -- ^ Configure 'Warp's behaviour |
91 | , printers :: Map API.PrinterId Printer | 90 | , printers :: Map API.PrinterId Printer |
92 | , queueManagers :: API.PrinterId -> QMConfig | 91 | , queueManagers :: API.PrinterId -> QMConfig m |
93 | } | 92 | } |
94 | 93 | ||
94 | data QMConfig m = forall t. ( MonadTrans t | ||
95 | , MFunctor t | ||
96 | , Monad (t STM) | ||
97 | , MonadIO (t IO) | ||
98 | ) => QMConfig { manager :: QueueManager t | ||
99 | , collapse :: (t IO) :~> m | ||
100 | } | ||
101 | |||
95 | instance MonadIO m => Default (Config m) where | 102 | instance MonadIO m => Default (Config m) where |
96 | def = Config { dyreError = Nothing | 103 | def = Config { dyreError = Nothing |
97 | , warpSettings = Warp.defaultSettings | 104 | , warpSettings = Warp.defaultSettings |
@@ -99,7 +106,10 @@ instance MonadIO m => Default (Config m) where | |||
99 | , queueManagers = const def | 106 | , queueManagers = const def |
100 | } | 107 | } |
101 | 108 | ||
102 | withPrinters :: MonadResource m => Config m -> [(m PrinterMethod, QMConfig)] -> m (Config m) | 109 | instance MonadIO m => Default (QMConfig m) where |
110 | def = QMConfig idQM $ Nat (liftIO . runIdentityT) | ||
111 | |||
112 | withPrinters :: MonadResource m => Config m -> [(m PrinterMethod, QMConfig m)] -> m (Config m) | ||
103 | -- ^ Add a list of printers to a 'Config' | 113 | -- ^ Add a list of printers to a 'Config' |
104 | withPrinters cfg = fmap updateCfg . foldlM mapInsert (Map.mapWithKey (\k a -> (a, queueManagers cfg k)) $ printers cfg) | 114 | withPrinters cfg = fmap updateCfg . foldlM mapInsert (Map.mapWithKey (\k a -> (a, queueManagers cfg k)) $ printers cfg) |
105 | where | 115 | where |
@@ -140,7 +150,7 @@ thermoprintServer dyre io = Dyre.wrapMain $ Dyre.defaultParams | |||
140 | gcChan <- liftIO newTChanIO | 150 | gcChan <- liftIO newTChanIO |
141 | fork tMgr $ jobGC gcChan | 151 | fork tMgr $ jobGC gcChan |
142 | let | 152 | let |
143 | runQM' = liftIO . runQM gcChan . queueManagers | 153 | runQM' (queueManagers -> QMConfig qm nat) printer = unNat nat $ runQM gcChan qm printer |
144 | mapM_ (fork tMgr . uncurry runQM') $ Map.toList printers | 154 | mapM_ (fork tMgr . uncurry runQM') $ Map.toList printers |
145 | nChan <- liftIO $ newBroadcastTChanIO | 155 | nChan <- liftIO $ newBroadcastTChanIO |
146 | let | 156 | let |
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 | |||
14 | module Thermoprint.Server.QMConfig | ||
15 | ( QMConfig(..) | ||
16 | , nullQM | ||
17 | , idQM | ||
18 | , standardSleep | ||
19 | , limitHistorySize | ||
20 | , limitHistoryAge | ||
21 | ) where | ||
22 | |||
23 | import Control.Monad.Trans.Resource | ||
24 | import Control.Monad.Trans.Control | ||
25 | import Control.Monad.Trans.Identity | ||
26 | import Control.Monad.Logger | ||
27 | import Control.Monad.Reader | ||
28 | import Control.Monad.IO.Class | ||
29 | import Control.Monad.Morph | ||
30 | import Control.Monad.Trans.Compose | ||
31 | import Control.Monad.State | ||
32 | import Control.Category | ||
33 | import Servant.Server.Internal.Enter | ||
34 | |||
35 | import Data.Constraint | ||
36 | import Data.Constraint.Forall | ||
37 | |||
38 | import Data.Default.Class | ||
39 | |||
40 | import Data.Sequence (Seq) | ||
41 | import qualified Data.Sequence as Seq | ||
42 | import Data.Time | ||
43 | import Data.Foldable | ||
44 | |||
45 | import Control.Concurrent.STM | ||
46 | |||
47 | import Thermoprint.Server.Queue hiding (idQM, intersection, nullQM, union, runQM) | ||
48 | import qualified Thermoprint.Server.Queue as Q | ||
49 | |||
50 | import Thermoprint.Server.Database (JobId) | ||
51 | |||
52 | import Prelude hiding (length, maximum, id, (.)) | ||
53 | |||
54 | type 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 | |||
62 | class QMTrans1 (t :: (* -> *) -> * -> *) (t' :: (* -> *) -> * -> *) | ||
63 | instance QMTrans (ComposeT t t') => QMTrans1 t t' | ||
64 | |||
65 | type QMTrans' t = (QMTrans t, Forall (QMTrans1 t)) | ||
66 | |||
67 | data 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 | |||
72 | instance Default QMConfig where | ||
73 | def = idQM | ||
74 | |||
75 | intersection :: Foldable f => f QMConfig -> QMConfig | ||
76 | intersection = foldr' (qmCombine Q.intersection) idQM | ||
77 | |||
78 | idQM :: QMConfig | ||
79 | idQM = QMConfig' Q.idQM | ||
80 | |||
81 | union :: Foldable f => f QMConfig -> QMConfig | ||
82 | union = foldr' (qmCombine Q.union) idQM | ||
83 | |||
84 | nullQM :: QMConfig | ||
85 | nullQM = QMConfig' Q.nullQM | ||
86 | |||
87 | qmCombine :: (forall f t. (Foldable f, MonadState Queue (QueueManagerM t)) => f (QueueManager t) -> QueueManager t) -> QMConfig -> QMConfig -> QMConfig | ||
88 | qmCombine 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 | |||
93 | natComp :: (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 | ) | ||
99 | natComp natA natB = natA . hoistNat natB . Nat getComposeT | ||
100 | |||
101 | runQM :: ( HasQueue q ) => TChan JobId -> QMConfig -> q -> IO () | ||
102 | runQM gcChan (QMConfig qm nat) q = unNat nat $ Q.runQM gcChan qm q | ||
103 | runQM gcChan (QMConfig' qm) q = runIdentityT $ Q.runQM gcChan qm q | ||
104 | |||
105 | standardSleep :: 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) | ||
109 | standardSleep = return $ 20 | ||
110 | |||
111 | limitHistorySize :: Int -> QMConfig | ||
112 | -- ^ Limit a 'Queue's 'history's size to some number of 'QueueEntry's | ||
113 | limitHistorySize max = QMConfig' $ modify' limitSize >> standardSleep | ||
114 | where | ||
115 | limitSize :: Queue -> Queue | ||
116 | limitSize q@Queue{..} = q { history = Seq.take max history } | ||
117 | |||
118 | limitHistoryAge :: 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 | ||
121 | limitHistoryAge 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 | ||
diff --git a/server/test/Thermoprint/ServerSpec.hs b/server/test/Thermoprint/ServerSpec.hs index 6407c3c..028ba2d 100644 --- a/server/test/Thermoprint/ServerSpec.hs +++ b/server/test/Thermoprint/ServerSpec.hs | |||
@@ -13,8 +13,7 @@ import qualified Test.Hspec as Hspec | |||
13 | import Test.QuickCheck | 13 | import Test.QuickCheck |
14 | 14 | ||
15 | import Thermoprint.API | 15 | import Thermoprint.API |
16 | import qualified Thermoprint.Server as S hiding (intersection, idQM, union, nullQM) | 16 | import qualified Thermoprint.Server as S |
17 | import qualified Thermoprint.Server.Queue as S | ||
18 | import Thermoprint.Client | 17 | import Thermoprint.Client |
19 | 18 | ||
20 | import Data.Monoid | 19 | import Data.Monoid |
diff --git a/server/thermoprint-server.cabal b/server/thermoprint-server.cabal index 0a5690e..3f0f832 100644 --- a/server/thermoprint-server.cabal +++ b/server/thermoprint-server.cabal | |||
@@ -18,7 +18,6 @@ cabal-version: >=1.10 | |||
18 | 18 | ||
19 | library | 19 | library |
20 | exposed-modules: Thermoprint.Server | 20 | exposed-modules: Thermoprint.Server |
21 | , Thermoprint.Server.QMConfig | ||
22 | , Thermoprint.Server.Fork | 21 | , Thermoprint.Server.Fork |
23 | , Thermoprint.Server.Database | 22 | , Thermoprint.Server.Database |
24 | , Thermoprint.Server.API | 23 | , Thermoprint.Server.API |
@@ -66,7 +65,6 @@ library | |||
66 | , wai-websockets >=3.0.0 && <4 | 65 | , wai-websockets >=3.0.0 && <4 |
67 | , wai >=3.0.5 && <4 | 66 | , wai >=3.0.5 && <4 |
68 | , network-uri >=2.6.0 && <3 | 67 | , network-uri >=2.6.0 && <3 |
69 | , constraints >=0.8 && <1 | ||
70 | hs-source-dirs: src | 68 | hs-source-dirs: src |
71 | default-language: Haskell2010 | 69 | default-language: Haskell2010 |
72 | ghc-options: -Wall | 70 | ghc-options: -Wall |
diff --git a/server/thermoprint-server.nix b/server/thermoprint-server.nix index ff8ebd4..6ff8b10 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 | , constraints, containers, data-default-class, deepseq, dyre | 2 | , containers, data-default-class, deepseq, dyre, either, encoding |
3 | , either, encoding, exceptions, extended-reals, filelock, hspec | 3 | , exceptions, extended-reals, filelock, hspec, mmorph |
4 | , mmorph, monad-control, monad-logger, mtl, network-uri, persistent | 4 | , 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,13 +14,12 @@ mkDerivation { | |||
14 | isLibrary = true; | 14 | isLibrary = true; |
15 | isExecutable = true; | 15 | isExecutable = true; |
16 | libraryHaskellDepends = [ | 16 | libraryHaskellDepends = [ |
17 | base binary bytestring conduit constraints containers | 17 | base binary bytestring conduit containers data-default-class |
18 | data-default-class deepseq dyre either encoding exceptions | 18 | deepseq dyre either encoding exceptions extended-reals filelock |
19 | extended-reals filelock mmorph monad-control monad-logger mtl | 19 | mmorph monad-control monad-logger mtl network-uri persistent |
20 | network-uri persistent persistent-template QuickCheck | 20 | persistent-template QuickCheck quickcheck-instances resourcet |
21 | quickcheck-instances resourcet servant servant-server stm text | 21 | servant servant-server stm text thermoprint-spec time transformers |
22 | thermoprint-spec time transformers wai wai-websockets warp | 22 | wai wai-websockets warp websockets |
23 | websockets | ||
24 | ]; | 23 | ]; |
25 | executableHaskellDepends = [ | 24 | executableHaskellDepends = [ |
26 | base monad-logger mtl persistent-sqlite resourcet | 25 | base monad-logger mtl persistent-sqlite resourcet |