diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a3f672..f552950 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: ACTIONS_ALLOW_UNSECURE_COMMANDS: true strategy: matrix: - os: [ubuntu-latest] + os: [ubuntu-latest, windows] stack: ["2.11.1"] ghc: ["8.8.4", "8.10.7", "9.2.8", "9.4.5"] diff --git a/odd-jobs.cabal b/odd-jobs.cabal index 94af975..8d0c831 100644 --- a/odd-jobs.cabal +++ b/odd-jobs.cabal @@ -81,7 +81,6 @@ library , filepath , friendly-time , generic-deriving - , hdaemonize , hostname , lucid , monad-control @@ -100,12 +99,15 @@ library , text-conversions , time , timing-convenience - , unix , unliftio , unliftio-core , unordered-containers , wai , warp + if !os(windows) + build-depends: + hdaemonize + , unix default-language: Haskell2010 executable devel @@ -144,7 +146,6 @@ executable devel , foreign-store , friendly-time , generic-deriving - , hdaemonize , hostname , lucid , monad-control @@ -164,12 +165,15 @@ executable devel , text-conversions , time , timing-convenience - , unix , unliftio , unliftio-core , unordered-containers , wai , warp + if !os(windows) + build-depends: + hdaemonize + , unix default-language: Haskell2010 executable odd-jobs-cli-example @@ -198,7 +202,6 @@ executable odd-jobs-cli-example , filepath , friendly-time , generic-deriving - , hdaemonize , hostname , lucid , monad-control @@ -218,12 +221,15 @@ executable odd-jobs-cli-example , text-conversions , time , timing-convenience - , unix , unliftio , unliftio-core , unordered-containers , wai , warp + if !os(windows) + build-depends: + hdaemonize + , unix default-language: Haskell2010 test-suite jobrunner @@ -264,7 +270,6 @@ test-suite jobrunner , filepath , friendly-time , generic-deriving - , hdaemonize , hedgehog , hostname , lifted-async @@ -292,10 +297,13 @@ test-suite jobrunner , text-conversions , time , timing-convenience - , unix , unliftio , unliftio-core , unordered-containers , wai , warp + if !os(windows) + build-depends: + hdaemonize + , unix default-language: Haskell2010 diff --git a/src/OddJobs/Cli.hs b/src/OddJobs/Cli.hs index 789e7ce..26caa63 100644 --- a/src/OddJobs/Cli.hs +++ b/src/OddJobs/Cli.hs @@ -2,6 +2,8 @@ {-# LANGUAGE PartialTypeSignatures #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE DataKinds #-} +{-# LANGUAGE CPP #-} + module OddJobs.Cli where import Options.Applicative as Opts @@ -12,14 +14,10 @@ import Data.Functor (void) import Data.Text import OddJobs.Job (startJobRunner, Config(..), LogLevel(..), LogEvent(..)) import OddJobs.Types (UIConfig(..), Seconds(..), delaySeconds) -import qualified System.Posix.Daemonize as Daemonize import System.FilePath (FilePath, takeBaseName, takeDirectory) -import System.Posix.Process (getProcessID) -import System.Posix.Signals (Handler(CatchOnce), installHandler, sigTERM) import qualified System.Directory as Dir import qualified System.Exit as Exit import System.Environment (getProgName) -import qualified System.Posix.Signals as Sig import qualified UnliftIO.Async as Async import UnliftIO (bracket_) import Safe (fromJustNote) @@ -31,6 +29,10 @@ import Data.Text.Encoding (decodeUtf8) import Network.Wai.Handler.Warp as Warp import Debug.Trace import Data.String.Conv (toS) +#ifndef mingw32_HOST_OS +import qualified System.Posix.Daemonize as Daemonize +import System.Posix.Signals (Handler(CatchOnce), installHandler, sigTERM) +#endif -- * Introduction -- @@ -125,7 +127,9 @@ withGracefulTermination ioAction = do var <- newEmptyMVar let terminate = void $ tryPutMVar var () waitForTermination = takeMVar var +#ifndef mingw32_HOST_OS void $ installHandler sigTERM (CatchOnce terminate) Nothing +#endif either (const Nothing) Just <$> race waitForTermination ioAction -- | Like 'withGracefulTermination' but ignoring the return value @@ -147,12 +151,16 @@ defaultStartCommand :: CommonStartArgs -> IO () defaultStartCommand CommonStartArgs{..} mUIArgs cliType = do if startDaemonize then do +#ifdef mingw32_HOST_OS + error "daemons not supported on windows" +#else Daemonize.serviced $ Daemonize.simpleDaemon { Daemonize.program = \() -> withGracefulTermination_ coreStartupFn , Daemonize.name = Just $ takeBaseName startPidFile , Daemonize.pidfileDirectory = Just $ takeDirectory startPidFile } +#endif else coreStartupFn where diff --git a/src/OddJobs/Job.hs b/src/OddJobs/Job.hs index f93f78a..f601dc2 100644 --- a/src/OddJobs/Job.hs +++ b/src/OddJobs/Job.hs @@ -1,5 +1,6 @@ {-# LANGUAGE RankNTypes, FlexibleInstances, FlexibleContexts, PartialTypeSignatures, UndecidableInstances #-} {-# LANGUAGE ExistentialQuantification, RecordWildCards, ScopedTypeVariables #-} +{-# LANGUAGE CPP #-} module OddJobs.Job ( @@ -90,7 +91,6 @@ import Database.PostgreSQL.Simple.Notification import UnliftIO.Async hiding (poll) import UnliftIO.Concurrent (threadDelay, myThreadId) import Data.String -import System.Posix.Process (getProcessID) import Network.HostName (getHostName) import UnliftIO.MVar import Debug.Trace @@ -127,6 +127,9 @@ import Prelude hiding (log) import GHC.Exts (toList) import Database.PostgreSQL.Simple.Types as PGS (Identifier(..)) import Database.PostgreSQL.Simple.ToField as PGS (toField) +#ifndef mingw32_HOST_OS +import System.Posix.Process (getProcessID) +#endif -- | The documentation of odd-jobs currently promotes 'startJobRunner', which -- expects a fairly detailed 'Config' record, as a top-level function for @@ -228,7 +231,16 @@ startJobRunner jm = do jobWorkerName :: IO String jobWorkerName = do +#ifndef mingw32_HOST_OS pid <- getProcessID +#else + -- assign it to a random number for windows. + -- not sure if it impacts anything if this function is called twice, + -- we don't have a global id like on unix for a process + -- so all will be 42 for now (unless this causes issues, then change it) + let pid = 42 +#endif + hname <- getHostName pure $ hname ++ ":" ++ show pid