packages feed

systemd-socket-activation 1.0.0.1 → 1.0.0.2

raw patch · 12 files changed

+163/−140 lines, 12 filesdep ~basedep ~containersdep ~networkPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, containers, network, text

API changes (from Hackage documentation)

Files

+ changelog.md view
@@ -0,0 +1,11 @@+# 1.0.0.2 (2023-01-08)++Support GHC 9.4++# 1.0.0.1 (2021-12-27)++Support GHC 9.2++# 1 (2021-07-07)++Initial release
+ readme.md view
@@ -0,0 +1,8 @@+"Socket activation" is the a feature of systemd. ([documentation])++We use it for web servers, to avoid the momentary downtime that otherwise occurs+while restarting processes. Because the socket is manged by systemd, not by our+process, the socket remains even while our process is down. Requests to the+socket are queued until our process comes back up to respond.++  [documentation]: https://www.freedesktop.org/software/systemd/man/sd_listen_fds_with_names.html
src/SocketActivation.hs view
@@ -1,29 +1,26 @@ module SocketActivation     (-    -- * Actions-      getMySocketByName--    -- * Types-    , Name (..), VarName (..), Socket, Error (..)--    ) where+        {- * Actions -} getMySocketByName,+        {- * Types -} Name (..), VarName (..), Socket, Error (..),+    )+    where -import           Control.Applicative             (Applicative ((*>)))-import           Control.Monad                   (Monad (return, (>>=)))-import           Data.Either                     (Either, either)-import           System.IO                       (IO, print)+import Control.Applicative (Applicative ((*>)))+import Control.Monad (Monad (return, (>>=)))+import Data.Either (Either, either)+import System.IO (IO, print) -import qualified Control.Exception               as Ex+import qualified Control.Exception as Ex  import qualified SocketActivation.CheckRecipient as SA-import qualified SocketActivation.Concepts       as SA-import qualified SocketActivation.Env            as SA-import qualified SocketActivation.GetByName      as SA+import qualified SocketActivation.Env as SA+import qualified SocketActivation.GetByName as SA -import           SocketActivation.Concepts       as Concepts+import SocketActivation.Concepts+    (Socket, Error (..), VarName (..), Name (..)) -getMySocketByName :: SA.Name -> IO SA.Socket+getMySocketByName :: Name -> IO Socket getMySocketByName name = f SA.checkRecipient *> f (SA.getSocketByName name)   where-    f :: IO (Either SA.Error a) -> IO a+    f :: IO (Either Error a) -> IO a     f = (>>= either (\e -> (SA.getEnvVars >>= print) *> Ex.throw e) return)
src/SocketActivation/CheckRecipient.hs view
@@ -2,18 +2,18 @@  module SocketActivation.CheckRecipient where -import           Control.Monad             (Monad (return, (>>=)))-import           Control.Monad.IO.Class    (MonadIO (liftIO))-import           Data.Either               (Either)-import           Data.Eq                   (Eq ((==)))-import           Data.Function             ((.))-import           System.IO                 (IO)+import Control.Monad (Monad (return, (>>=)))+import Control.Monad.IO.Class (MonadIO (liftIO))+import Data.Either (Either)+import Data.Eq (Eq ((==)))+import Data.Function ((.))+import System.IO (IO) -import qualified System.Posix.Process      as Sys+import qualified System.Posix.Process as Sys -import           SocketActivation.Concepts-import           SocketActivation.Env-import           SocketActivation.IO+import SocketActivation.Concepts (Error(WrongProcess), Recipient (recipientPID))+import SocketActivation.Env (getEnv')+import SocketActivation.IO (IO' (IO', run), throwError)  checkRecipient :: IO (Either Error ()) checkRecipient = run (getIt >>= checkIt)@@ -25,4 +25,5 @@ checkRecipient' x = run (getMyPid >>= throwIfDifferent)   where     getMyPid = liftIO Sys.getProcessID-    throwIfDifferent y = if recipientPID x == y then return () else throwError WrongProcess+    throwIfDifferent y =+        if recipientPID x == y then return () else throwError WrongProcess
src/SocketActivation/Concepts.hs view
@@ -1,38 +1,46 @@ module SocketActivation.Concepts-  ( Recipient (..)-  , ProcessID-  , Count (..)-  , Name (..)-  , Names (..)-  , VarName (..)-  , Fd (..)-  , Socket-  , Error (..)-  ) where+    (+        Recipient (..),+        ProcessID,+        Count (..),+        Name (..),+        Names (..),+        VarName (..),+        Fd (..),+        Socket,+        Error (..),+    )+    where -import           Control.Exception  (Exception)-import           Data.String        (IsString)-import           Data.Text          (Text)-import           Numeric.Natural    (Natural)-import           Prelude            (Bounded, Enum, Eq, Ord, Show)+import Control.Exception (Exception)+import Data.String (IsString)+import Data.Text (Text)+import Numeric.Natural (Natural)+import Prelude (Bounded, Enum, Eq, Ord, Show) -import           Network.Socket     (Socket)-import           System.Posix.Types (Fd (..), ProcessID)+import Network.Socket (Socket)+import System.Posix.Types (Fd (..), ProcessID) --- | The ID of the process to whom systemd has given the sockets. A process should not use sockets that are intended for someone else, so we should always check that this matches our own PID before proceeding doing anything with the sockets.+{-| The ID of the process to whom systemd has given the sockets++A process should not use sockets that are intended for someone else, so we+should always check that this matches our own PID before proceeding doing+anything with the sockets. -} newtype Recipient = RecipientPID { recipientPID :: ProcessID }     deriving stock (Eq, Show) --- | The number of sockets that systemd has given the process.+{-| The number of sockets that systemd has given the process -} newtype Count = CountNat { countNat :: Natural }     deriving stock (Eq, Show) --- | The name of a socket, corresponding to the socket's FileDescriptorName in the systemd config.+{-| The name of a socket, corresponding to the socket's FileDescriptorName in+    the systemd config -} newtype Name = NameText { nameText :: Text }     deriving stock (Eq, Ord, Show)     deriving newtype IsString --- | The names of the sockets that we have been given, corresponding to the FileDescriptorName of each systemd socket.+{-| The names of the sockets that we have been given, corresponding to the+    FileDescriptorName of each systemd socket -} newtype Names = NamesList { namesList :: [Name] }     deriving stock (Eq, Show) 
src/SocketActivation/Env.hs view
@@ -1,22 +1,23 @@ module SocketActivation.Env where -import           Control.Monad             (Monad (return, (>>=)))-import           Control.Monad.IO.Class    (MonadIO (liftIO))-import           Data.Either               (Either, either)-import           Data.Function             (($), (.))-import           Data.Maybe                (Maybe (..), maybe)-import           Data.Text                 (Text)-import           Data.Traversable          (Traversable (traverse))-import           Prelude                   (Bounded (maxBound, minBound))-import           System.IO                 (IO)-import           Text.Show                 (show)+import Control.Monad (Monad (return, (>>=)))+import Control.Monad.IO.Class (MonadIO (liftIO))+import Data.Either (Either, either)+import Data.Function (($), (.))+import Data.Maybe (Maybe (..), maybe)+import Data.Text (Text)+import Data.Traversable (Traversable (traverse))+import Prelude (Bounded (maxBound, minBound))+import System.IO (IO)+import Text.Show (show) -import qualified Data.Text                 as Text-import qualified System.Environment        as Sys+import qualified Data.Text as Text+import qualified System.Environment as Sys -import           SocketActivation.Concepts-import           SocketActivation.IO-import           SocketActivation.Parsing+import SocketActivation.Concepts+    (Error (Invalid, Missing), VarName (..), Names, Count, Recipient)+import SocketActivation.IO (IO' (IO', run), throwError)+import SocketActivation.Parsing (readRecipient, readCount, readNames)  getVarText :: VarName -> IO (Either Error Text) getVarText name = run (getMaybe >>= throwIfMissing >>= pack)@@ -26,7 +27,11 @@     pack = return . Text.pack  getEnvVars :: IO [(VarName, Maybe Text)]-getEnvVars = traverse (\x -> getVarText x >>= \y -> return (x, either (\_ -> Nothing) Just y)) [minBound .. maxBound]+getEnvVars =+    traverse+        (\x -> getVarText x >>= \y ->+            return (x, either (\_ -> Nothing) Just y))+        [minBound .. maxBound]  data Env a = Env VarName (Text -> Maybe a) 
src/SocketActivation/GetByName.hs view
@@ -1,23 +1,23 @@ module SocketActivation.GetByName where -import           Control.Applicative                 (Applicative ((<*>)),-                                                      (<$>))-import           Control.Monad                       (Monad (return, (>>=)))-import           Control.Monad.IO.Class              (MonadIO (liftIO))-import           Data.Either                         (Either)-import           Data.Function                       ((.))-import           Data.List                           (zip)-import           Data.Map                            (Map)-import           Data.Maybe                          (maybe)-import           System.IO                           (IO)+import Control.Applicative (Applicative ((<*>)), (<$>))+import Control.Monad (Monad (return, (>>=)))+import Control.Monad.IO.Class (MonadIO (liftIO))+import Data.Either (Either)+import Data.Function ((.))+import Data.List (zip)+import Data.Map (Map)+import Data.Maybe (maybe)+import System.IO (IO) -import qualified Data.Map                            as Map+import qualified Data.Map as Map -import           SocketActivation.Concepts-import           SocketActivation.Env-import           SocketActivation.GetFileDescriptors-import           SocketActivation.GetSockets-import           SocketActivation.IO+import SocketActivation.Concepts+    (Socket, Fd, Error (NoSuchName), Names (namesList), Name)+import SocketActivation.Env (getEnv')+import SocketActivation.GetFileDescriptors (getFileDescriptorList)+import SocketActivation.GetSockets (getSocketList, fdSocket)+import SocketActivation.IO (IO' (IO', run), throwError)  getNameList :: IO (Either Error [Name]) getNameList = run (getNames >>= unwrap)
src/SocketActivation/GetFileDescriptors.hs view
@@ -1,19 +1,19 @@ module SocketActivation.GetFileDescriptors where -import           Control.Monad             (Monad (return, (>>=)))-import           Data.Either               (Either)-import           Data.Function             ((.))-import           Data.Int                  (Int)-import           Data.List                 (take)-import           Numeric.Natural           (Natural)-import           Prelude                   (fromIntegral)-import           System.IO                 (IO)+import Control.Monad (Monad (return, (>>=)))+import Data.Either (Either)+import Data.Function ((.))+import Data.Int (Int)+import Data.List (take)+import Numeric.Natural (Natural)+import Prelude (fromIntegral)+import System.IO (IO) -import           SocketActivation.Concepts-import           SocketActivation.Env-import           SocketActivation.IO+import SocketActivation.Concepts (Fd (..), Error, Count (countNat))+import SocketActivation.Env (getEnv')+import SocketActivation.IO (IO' (IO', run)) --- | Get a list of file descriptors for the sockets.+{-| Get a list of file descriptors for the sockets -} getFileDescriptorList :: IO (Either Error [Fd]) getFileDescriptorList = run (getCount >>= enumerateFds)   where
src/SocketActivation/GetSockets.hs view
@@ -1,17 +1,17 @@ module SocketActivation.GetSockets where -import           Control.Monad                       (Monad ((>>=)))-import           Control.Monad.IO.Class              (MonadIO (liftIO))-import           Data.Either                         (Either)-import           Data.Function                       ((.))-import           Data.Traversable                    (Traversable (traverse))-import           System.IO                           (IO)+import Control.Monad (Monad ((>>=)))+import Control.Monad.IO.Class (MonadIO (liftIO))+import Data.Either (Either)+import Data.Function ((.))+import Data.Traversable (Traversable (traverse))+import System.IO (IO) -import qualified Network.Socket                      as Net+import qualified Network.Socket as Net -import           SocketActivation.Concepts-import           SocketActivation.GetFileDescriptors-import           SocketActivation.IO+import SocketActivation.Concepts (Socket, Fd (..), Error)+import SocketActivation.GetFileDescriptors (getFileDescriptorList)+import SocketActivation.IO (IO' (IO', run))  getSocketList :: IO (Either Error [Socket]) getSocketList = run (getFds >>= convertToSockets)
src/SocketActivation/IO.hs view
@@ -1,14 +1,14 @@ module SocketActivation.IO where -import           Control.Applicative        (Applicative)-import           Control.Monad              (Functor, Monad (return))-import           Control.Monad.IO.Class     (MonadIO)-import           Control.Monad.Trans.Except (ExceptT (..))-import           Data.Either                (Either (Left))-import           Data.Function              ((.))-import           System.IO                  (IO)+import Control.Applicative (Applicative)+import Control.Monad (Functor, Monad (return))+import Control.Monad.IO.Class (MonadIO)+import Control.Monad.Trans.Except (ExceptT (..))+import Data.Either (Either (Left))+import Data.Function ((.))+import System.IO (IO) -import           SocketActivation.Concepts+import SocketActivation.Concepts (Error)  newtype IO' a = IO' { run :: IO (Either Error a) }     deriving (Functor, Applicative, Monad, MonadIO) via ExceptT Error IO
src/SocketActivation/Parsing.hs view
@@ -1,18 +1,17 @@ module SocketActivation.Parsing where -import           Control.Monad             (Functor (fmap), Monad (return),-                                            (>=>))-import           Data.Bits                 (toIntegralSized)-import           Data.Function             ((.))-import           Data.Maybe                (Maybe)-import           Data.Text                 (Text)-import           Foreign.C.Types           (CInt)-import           Numeric.Natural           (Natural)-import           Text.Read                 (readMaybe)+import Control.Monad (Functor (fmap), Monad (return), (>=>))+import Data.Bits (toIntegralSized)+import Data.Function ((.))+import Data.Maybe (Maybe)+import Data.Text (Text)+import Foreign.C.Types (CInt)+import Numeric.Natural (Natural)+import Text.Read (readMaybe) -import qualified Data.Text                 as Text+import qualified Data.Text as Text -import           SocketActivation.Concepts+import SocketActivation.Concepts  readRecipient :: Text -> Maybe Recipient readRecipient = read >=> wrap
systemd-socket-activation.cabal view
@@ -1,21 +1,15 @@ cabal-version: 3.0  name: systemd-socket-activation-version: 1.0.0.1+version: 1.0.0.2 category: System, Network synopsis: Let systemd bind the server's socket for you -description:-    "Socket activation" is the a feature of systemd.--    https://www.freedesktop.org/software/systemd/man/sd_listen_fds_with_names.html--    We use it for web servers, to avoid the momentary downtime-    that otherwise occurs while restarting processes.-    Because the socket is manged by systemd, not by our process,-    the socket remains even while our process is down.-    Requests to the socket are queued until our process comes-    back up to respond.+description: "Socket activation" is the a feature of systemd. We use it for web+    servers, to avoid the momentary downtime that otherwise occurs while restarting+    processes. Because the socket is manged by systemd, not by our process, the+    socket remains even while our process is down. Requests to the socket are queued+    until our process comes back up to respond.  copyright: 2021 Mission Valley Software LLC license: MIT@@ -27,7 +21,7 @@ homepage:    https://github.com/typeclasses/systemd-socket-activation bug-reports: https://github.com/typeclasses/systemd-socket-activation/issues -build-type: Simple+extra-source-files: *.md  source-repository head   type: git@@ -56,9 +50,9 @@         SocketActivation.Parsing      build-depends:-        base         ^>= 4.14 || ^>= 4.15 || ^>= 4.16-      , containers   ^>= 0.6-      , network      ^>= 3.1-      , text         ^>= 1.2.3+      , base         ^>= 4.14 || ^>= 4.15 || ^>= 4.16 || ^>= 4.17+      , containers   ^>= 0.6.4+      , network      ^>= 3.1.2+      , text         ^>= 1.2.4 || ^>= 2.0       , transformers ^>= 0.5.6 || ^>= 0.6       , unix         ^>= 2.7.2