aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2016-01-23 13:58:16 +0000
committerGregor Kleen <gkleen@yggdrasil.li>2016-01-23 13:58:16 +0000
commit0a5b8082e5ddcd22b846cc7c145af2468c542fa4 (patch)
tree6c451253a17569ed5f7d1c1942a150863083e2b3
parent19df7b59fef57b75d6dc6d23dc0cd0c79bc39028 (diff)
downloadthermoprint-0a5b8082e5ddcd22b846cc7c145af2468c542fa4.tar
thermoprint-0a5b8082e5ddcd22b846cc7c145af2468c542fa4.tar.gz
thermoprint-0a5b8082e5ddcd22b846cc7c145af2468c542fa4.tar.bz2
thermoprint-0a5b8082e5ddcd22b846cc7c145af2468c542fa4.tar.xz
thermoprint-0a5b8082e5ddcd22b846cc7c145af2468c542fa4.zip
runPrinter
-rw-r--r--server/src/Thermoprint/Server/Printer.hs65
-rw-r--r--server/thermoprint-server.cabal1
-rw-r--r--server/thermoprint-server.nix10
3 files changed, 64 insertions, 12 deletions
diff --git a/server/src/Thermoprint/Server/Printer.hs b/server/src/Thermoprint/Server/Printer.hs
index e66afff..0db98a0 100644
--- a/server/src/Thermoprint/Server/Printer.hs
+++ b/server/src/Thermoprint/Server/Printer.hs
@@ -1,29 +1,80 @@
1{-# LANGUAGE RankNTypes #-} 1{-# LANGUAGE RankNTypes #-}
2{-# LANGUAGE MultiParamTypeClasses #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE RecordWildCards #-}
5{-# LANGUAGE OverloadedStrings #-}
6{-# LANGUAGE TemplateHaskell #-}
7{-# LANGUAGE StandaloneDeriving #-}
8{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
2 9
3module Thermoprint.Server.Printer 10module Thermoprint.Server.Printer
4 ( Printer 11 ( Printer(..)
12 , Queue(..)
13 , runPrinter
5 ) where 14 ) where
6 15
7import Thermoprint.API (PrintingError(..), Printout) 16import Thermoprint.API (PrintingError(..), Printout)
17import qualified Thermoprint.API as API (JobStatus(..))
8 18
9import Thermoprint.Server.Database 19import Thermoprint.Server.Database
10 20
11import Database.Persist 21import Database.Persist
12import Database.Persist.Sql 22import Database.Persist.Sql
13 23
14import Data.Sequence (Seq, ViewL(..)) 24import Data.Sequence (Seq, ViewL(..), viewl, (<|))
15import qualified Data.Sequence as Seq 25import qualified Data.Sequence as Seq
16import Data.Map (Map) 26import Data.Map (Map)
17import qualified Data.Map as Map 27import qualified Data.Map as Map
18 28
19import Control.Monad.IO.Class (MonadIO) 29import qualified Data.Text as T (pack)
30
31import Data.Typeable (Typeable)
32import GHC.Generics (Generic)
33import Control.DeepSeq
34
35import Control.Monad.Trans.Resource
36import Control.Monad.IO.Class
37import Control.Monad.Logger
38import Control.Monad.Reader
39
40import Control.Monad (forever)
20 41
21import Control.Concurrent.STM 42import Control.Concurrent.STM
22 43
23data Printer = Printer 44data Printer = Printer
24 { print :: forall m. (MonadIO m) => Printout -> m (Maybe PrintingError) 45 { print :: forall m. (MonadIO m) => Printout -> m (Maybe PrintingError)
25 , queue :: TVar (Seq JobId) 46 , queue :: TVar Queue
26 } 47 }
27 48
28runPrinter :: Printer -> IO () 49-- | Zipper for 'Seq JobId'
29runPrinter = undefined 50data Queue = Queue
51 { pending :: Seq JobId -- ^ Pending jobs, closest first
52 , current :: Maybe JobId
53 , history :: Seq (JobId, Maybe PrintingError) -- ^ Completed jobs, closest first
54 }
55 deriving (Typeable, Generic, NFData)
56
57atomically' :: MonadIO m => STM a -> m a
58atomically' = liftIO . atomically
59
60runPrinter :: ( MonadReader ConnectionPool m
61 , MonadIO m
62 , MonadLogger m
63 , MonadBaseControl IO m
64 ) => Printer -> m ()
65-- ^ Loop 'forever' pushing entries from the 'Queue' associated to a 'Printer' into its 'print'-method
66runPrinter Printer{..} = forever $ do
67 jobId <- atomically' $ do
68 (Queue queuePending Nothing history) <- readTVar queue
69 case viewl queuePending of
70 EmptyL -> retry
71 (jobId :< remaining) -> do
72 writeTVar queue $!! Queue remaining (Just jobId) history
73 return jobId
74 job <- runSqlPool (get jobId) =<< ask
75 case job of
76 Nothing -> $(logWarn) "Nonexistent job id in printer queue"
77 Just job -> do
78 printReturn <- print (jobContent job)
79 maybe (return ()) ($(logWarn) . T.pack . (("Error while printing " ++ show jobId ++ ": ") ++) . show) $ printReturn
80 atomically' $ modifyTVar' queue (\Queue{..} -> force . Queue pending Nothing $ (jobId, printReturn) <| history)
diff --git a/server/thermoprint-server.cabal b/server/thermoprint-server.cabal
index 8862255..926118d 100644
--- a/server/thermoprint-server.cabal
+++ b/server/thermoprint-server.cabal
@@ -40,6 +40,7 @@ library
40 , either >=4.4.1 && <5 40 , either >=4.4.1 && <5
41 , text >=1.2.1 && <2 41 , text >=1.2.1 && <2
42 , stm >=2.4.4 && <3 42 , stm >=2.4.4 && <3
43 , deepseq >=1.4.1 && <2
43 hs-source-dirs: src 44 hs-source-dirs: src
44 default-language: Haskell2010 45 default-language: Haskell2010
45 46
diff --git a/server/thermoprint-server.nix b/server/thermoprint-server.nix
index 57e94a3..69bff1d 100644
--- a/server/thermoprint-server.nix
+++ b/server/thermoprint-server.nix
@@ -1,5 +1,5 @@
1{ mkDerivation, base, containers, data-default-class, dyre, either 1{ mkDerivation, base, containers, data-default-class, deepseq, dyre
2, monad-logger, mtl, persistent, persistent-sqlite 2, either, monad-logger, mtl, persistent, persistent-sqlite
3, persistent-template, resourcet, servant-server, stdenv, stm, text 3, persistent-template, resourcet, servant-server, stdenv, stm, text
4, thermoprint-spec, transformers, wai, warp 4, thermoprint-spec, transformers, wai, warp
5}: 5}:
@@ -10,9 +10,9 @@ mkDerivation {
10 isLibrary = true; 10 isLibrary = true;
11 isExecutable = true; 11 isExecutable = true;
12 libraryHaskellDepends = [ 12 libraryHaskellDepends = [
13 base containers data-default-class dyre either monad-logger mtl 13 base containers data-default-class deepseq dyre either monad-logger
14 persistent persistent-template resourcet servant-server stm text 14 mtl persistent persistent-template resourcet servant-server stm
15 thermoprint-spec transformers wai warp 15 text thermoprint-spec transformers wai warp
16 ]; 16 ];
17 executableHaskellDepends = [ 17 executableHaskellDepends = [
18 base monad-logger mtl persistent-sqlite resourcet 18 base monad-logger mtl persistent-sqlite resourcet