Safe Haskell | None |
---|---|
Language | Haskell2010 |
This module provides a function for loading a state value from a JSON
file, and a function which generates a safe scalable saver function. The
JSON files are written using the aeson-pretty
package, so that they are
easy to read and modify manually if needed.
The save function generator, mkSaveState
, returns a function which
saves settings when called, but only at most once in t
, the time interval
passed to the generator. For example, if you pass an interval of 3 seconds,
you can safely call the generated save function even 100 times a second, and
the JSON file will still get updated just once in 3 seconds, avoiding an
overload of file I/O.
The actual saving happens in a dedicated worker thread, so even when a save does occur, it won't block the caller thread. The generator can be called once at program start, and the returned save function saved in application state.
mkSaveStateVC
works similarly, but additionally provides a saver function
which commits the change into a git repo.
Note that while this simple periodic save-to-file method can serve a simple
standalone application well, it won't work if you wish your data to be
shared by multiple applications and allow them to read and write it at the
same time. If that's the case, check out the acid-state
package, and other
persistence related packages.
- loadState :: FromJSON s => FilePath -> IO (Either (Bool, String) s)
- mkSaveState :: (TimeUnit t, ToJSON s) => t -> FilePath -> IO (s -> IO ())
- mkSaveStateVC :: (TimeUnit t, ToJSON s) => t -> FilePath -> FilePath -> String -> IO (s -> IO (), s -> IO ())
- mkSaveStateChoose :: (TimeUnit t, ToJSON s) => t -> FilePath -> Maybe FilePath -> String -> IO (s -> IO ())
- stateFilePath :: FilePath -> Maybe FilePath -> FilePath
Documentation
:: (TimeUnit t, ToJSON s) | |
=> t | Minimal time interval between saves |
-> FilePath | File to save |
-> IO (s -> IO ()) |
Prepare a save action which writes state into a JSON file. This action defers the work to a separate dedicated thread, and ensures the file isn't saved more than once within the given time interval.
The action is non-blocking but there is a chance a save is missed if saves are triggered simultaneously from different threads.
You can call the returned action from your UI thread as a reaction to a state change, without worrying about delay or IO load.
:: (TimeUnit t, ToJSON s) | |
=> t | Minimal time interval between saves |
-> FilePath | File to save, path relative to repo path |
-> FilePath | Path of the Git repository |
-> String | Commit message to use in automatic commits |
-> IO (s -> IO (), s -> IO ()) |
Like mkSaveState
, but also takes a repository path. Creates a Git
repository there if there isn't yet. Two save actions are returned. The
first one simply saves state to a file, just like in mkSaveState
. The
second one saves to file and then commits it into the Git repository.
Note that the file path is relative to the repo path. For example, if you have the repo in "homejoerepo" and the file is "homejoerepo/file", pass just "file" as the file path.
:: (TimeUnit t, ToJSON s) | |
=> t | Minimal time interval between saves |
-> FilePath | File to save. If the repo path (next argument) is
|
-> Maybe FilePath | Optional path of the Git repository. If you pass
|
-> String | Commit message to use in automatic commits |
-> IO (s -> IO ()) |
This is a variant which returns a single save action, which either uses or
doesn't use a Git repo. If the repo path (3rd argument) is Nothing
, then
Git isn't used at all and the file path is treated like mkSaveState
would.
Otherwise, i.e. if a repo path is specified, the returned action will commit
changes to the Git repo, and the repo and file path arguments are treated
like mkSaveStateVC
would, i.e. the file path is relative to the repo.
If you use this function, also use stateFilePath
to determine the correct
path to pass to loadState
.
stateFilePath :: FilePath -> Maybe FilePath -> FilePath Source #
If you use mkSaveStateChoose
to save the state, that function combines
the repo path and the file path when needed, to determine the full path of
the state file. But then, how do you determine which path to pass to
loadState
? This is exactly what this function does. Pass it the optional
repo path and the file path you passed to mkSaveStateChoose
, and you'll
get a full path you can pass to loadState
.