Safe Haskell | None |
---|
Implementation of configuration reader with watching support.
Synopsis
- type ConfigReader = IO (Result ConfigData)
- data ReloadModel
- = ReloadNotify
- | ReloadPoll Int
- data ServerState = ServerState {
- reloadModel :: ReloadModel
- reloadTime :: Integer
- reloadFStat :: FStat
- maxIdlePollRounds :: Int
- watchInterval :: Int
- pollInterval :: Int
- reloadRatelimit :: Integer
- initialPoll :: ReloadModel
- data ConfigReload
- moveToPolling :: String -> INotify -> FilePath -> (Result ConfigData -> IO ()) -> MVar ServerState -> IO ReloadModel
- moveToNotify :: IO ReloadModel
- updateConfig :: FilePath -> (Result ConfigData -> IO ()) -> IO ()
- safeUpdateConfig :: FilePath -> FStat -> (Result ConfigData -> IO ()) -> IO (FStat, ConfigReload)
- onWatcherTimer :: FilePath -> (Result ConfigData -> IO ()) -> MVar ServerState -> IO ()
- onWatcherInner :: FilePath -> (Result ConfigData -> IO ()) -> ServerState -> IO ServerState
- onPollTimer :: IO Bool -> FilePath -> (Result ConfigData -> IO ()) -> MVar ServerState -> IO ()
- onPollInner :: IO Bool -> FilePath -> (Result ConfigData -> IO ()) -> ServerState -> IO (ServerState, Bool)
- addNotifier :: INotify -> FilePath -> (Result ConfigData -> IO ()) -> MVar ServerState -> IO Bool
- onInotify :: INotify -> String -> (Result ConfigData -> IO ()) -> MVar ServerState -> Event -> IO ()
- initConfigReader :: (Result ConfigData -> IO ()) -> IO ()
Documentation
type ConfigReader = IO (Result ConfigData) Source #
A type for functions that can return the configuration when executed.
data ReloadModel Source #
Reload model data type.
ReloadNotify | We are using notifications |
ReloadPoll Int | We are using polling |
data ServerState Source #
Server state data type.
ServerState | |
|
maxIdlePollRounds :: Int Source #
Maximum no-reload poll rounds before reverting to inotify.
watchInterval :: Int Source #
Reload timeout in microseconds.
pollInterval :: Int Source #
Ratelimit timeout in microseconds.
reloadRatelimit :: Integer Source #
Ratelimit timeout in microseconds, as an Integer
.
initialPoll :: ReloadModel Source #
Initial poll round.
data ConfigReload Source #
Reload status data type.
ConfigToDate | No need to reload |
ConfigReloaded | Configuration reloaded |
ConfigIOError | Error during configuration reload |
Configuration handling
Helper functions
moveToPolling :: String -> INotify -> FilePath -> (Result ConfigData -> IO ()) -> MVar ServerState -> IO ReloadModel Source #
Helper function for logging transition into polling mode.
moveToNotify :: IO ReloadModel Source #
Helper function for logging transition into inotify mode.
Configuration loading
updateConfig :: FilePath -> (Result ConfigData -> IO ()) -> IO () Source #
(Re)loads the configuration.
safeUpdateConfig :: FilePath -> FStat -> (Result ConfigData -> IO ()) -> IO (FStat, ConfigReload) Source #
Wrapper over updateConfig
that handles IO errors.
Watcher threads
We have three threads/functions that can mutate the server state:
- the long-interval watcher (
onWatcherTimer
) - the polling watcher (
onPollTimer
) - the inotify event handler (
onInotify
)
All of these will mutate the server state under modifyMVar
or
modifyMVar_
, so that server transitions are more or less
atomic. The inotify handler remains active during polling mode, but
checks for polling mode and doesn't do anything in this case (this
check is needed even if we would unregister the event handler due
to how events are serialised).
onWatcherTimer :: FilePath -> (Result ConfigData -> IO ()) -> MVar ServerState -> IO () Source #
Long-interval reload watcher.
This is on top of the inotify-based triggered reload.
onWatcherInner :: FilePath -> (Result ConfigData -> IO ()) -> ServerState -> IO ServerState Source #
Inner onWatcher handler.
This mutates the server state under a modifyMVar_ call. It never changes the reload model, just does a safety reload and tried to re-establish the inotify watcher.
onPollTimer :: IO Bool -> FilePath -> (Result ConfigData -> IO ()) -> MVar ServerState -> IO () Source #
Short-interval (polling) reload watcher.
This is only active when we're in polling mode; it will automatically exit when it detects that the state has changed to notification.
onPollInner :: IO Bool -> FilePath -> (Result ConfigData -> IO ()) -> ServerState -> IO (ServerState, Bool) Source #
Inner onPoll handler.
This again mutates the state under a modifyMVar call, and also returns whether the thread should continue or not.
addNotifier :: INotify -> FilePath -> (Result ConfigData -> IO ()) -> MVar ServerState -> IO Bool Source #
Setup inotify watcher.
This tries to setup the watch descriptor; in case of any IO errors, it will return False.
onInotify :: INotify -> String -> (Result ConfigData -> IO ()) -> MVar ServerState -> Event -> IO () Source #
Inotify event handler.
initConfigReader :: (Result ConfigData -> IO ()) -> IO () Source #