diff options
| -rw-r--r-- | server/src/Thermoprint/Server/Queue.hs | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/server/src/Thermoprint/Server/Queue.hs b/server/src/Thermoprint/Server/Queue.hs index 68dc7a9..17865b6 100644 --- a/server/src/Thermoprint/Server/Queue.hs +++ b/server/src/Thermoprint/Server/Queue.hs | |||
| @@ -15,9 +15,12 @@ import qualified Thermoprint.API as API (JobStatus(..)) | |||
| 15 | 15 | ||
| 16 | import Thermoprint.Server.Database | 16 | import Thermoprint.Server.Database |
| 17 | 17 | ||
| 18 | import Data.Sequence (Seq, ViewL(..), viewl) | 18 | import Data.Sequence (Seq, ViewL(..), viewl, (|>), (<|)) |
| 19 | import qualified Data.Sequence as Seq | 19 | import qualified Data.Sequence as Seq |
| 20 | 20 | ||
| 21 | import Data.Set (Set) | ||
| 22 | import qualified Data.Set as Set | ||
| 23 | |||
| 21 | import Data.Time | 24 | import Data.Time |
| 22 | import Data.Time.Clock | 25 | import Data.Time.Clock |
| 23 | 26 | ||
| @@ -34,6 +37,7 @@ import Data.Default.Class | |||
| 34 | import Control.Monad.Morph | 37 | import Control.Monad.Morph |
| 35 | import Control.Monad.Trans.Compose | 38 | import Control.Monad.Trans.Compose |
| 36 | 39 | ||
| 40 | import Data.Foldable | ||
| 37 | import Data.Monoid | 41 | import Data.Monoid |
| 38 | 42 | ||
| 39 | -- | Zipper for 'Seq QueueEntry' with additional support for 'PrintingError' in the section after point | 43 | -- | Zipper for 'Seq QueueEntry' with additional support for 'PrintingError' in the section after point |
| @@ -44,16 +48,32 @@ data Queue = Queue | |||
| 44 | } | 48 | } |
| 45 | deriving (Typeable, Generic, NFData) | 49 | deriving (Typeable, Generic, NFData) |
| 46 | 50 | ||
| 47 | toSeq :: Queue -> Seq (Bool, QueueEntry, Maybe PrintingError) | 51 | data QueueElem = Pending QueueEntry | Current QueueEntry | History QueueEntry (Maybe PrintingError) |
| 48 | toSeq Queue{..} = fmap (\x -> (False, x, Nothing)) pending <> maybe Seq.empty (\c -> Seq.singleton (True, c, Nothing)) current <> fmap (\(x, p) -> (False, x, p)) history | 52 | |
| 53 | instance Eq QueueElem where | ||
| 54 | (Pending a) == (Pending b) = a == b | ||
| 55 | (Current a) == (Current b) = a == b | ||
| 56 | (History a _) == (History b _) = a == b | ||
| 57 | _ == _ = False | ||
| 58 | |||
| 59 | instance Ord QueueElem where | ||
| 60 | (Pending _) <= _ = True | ||
| 61 | (Current _) <= (Pending _) = False | ||
| 62 | (Current _) <= _ = True | ||
| 63 | (History _ _) <= (History _ _) = True | ||
| 64 | (History _ _) <= _ = False | ||
| 49 | 65 | ||
| 50 | fromSeq :: Seq (Bool, QueueEntry, Maybe PrintingError) -> Queue | 66 | toSeq :: Queue -> Set (Int, QueueElem) |
| 51 | fromSeq s = Queue pending' current' history' | 67 | toSeq Queue{..} = fromSeq $ fmap Pending pending <> maybe Seq.empty (Seq.singleton . Current) current <> fmap (uncurry History) history |
| 52 | where | 68 | where |
| 53 | (fmap (\(_, x, _) -> x) -> pending', pending'') = Seq.breakl (\(c, _, _) -> c) s | 69 | fromSeq = Set.fromAscList . toList . Seq.mapWithIndex ((,)) |
| 54 | (current', history') = case viewl pending'' of | 70 | |
| 55 | EmptyL -> (Nothing, Seq.empty) | 71 | fromSeq :: Set (Int, QueueElem) -> Queue |
| 56 | (_, a, _) :< as -> (Just a, fmap (\(_, x, p) -> (x, p)) as) | 72 | fromSeq = foldr' (insert . snd) def |
| 73 | where | ||
| 74 | insert (Pending e) q@(Queue{..}) = q { pending = pending |> e } | ||
| 75 | insert (Current e) q = q { current = Just e } | ||
| 76 | insert (History e p) q@(Queue{..}) = q { history = history |> (e, p) } | ||
| 57 | 77 | ||
| 58 | class HasQueue a where | 78 | class HasQueue a where |
| 59 | extractQueue :: a -> TVar Queue | 79 | extractQueue :: a -> TVar Queue |
| @@ -72,7 +92,7 @@ data QueueEntry = QueueEntry | |||
| 72 | { jobId :: JobId | 92 | { jobId :: JobId |
| 73 | , created :: UTCTime | 93 | , created :: UTCTime |
| 74 | } | 94 | } |
| 75 | deriving (Typeable, Generic, NFData) | 95 | deriving (Typeable, Generic, NFData, Eq) |
| 76 | 96 | ||
| 77 | -- | A queue manager periodically modifies a 'Queue', e.g. for cleanup of old jobs | 97 | -- | A queue manager periodically modifies a 'Queue', e.g. for cleanup of old jobs |
| 78 | type QueueManager t = ComposeT (StateT Queue) t STM DiffTime | 98 | type QueueManager t = ComposeT (StateT Queue) t STM DiffTime |
