persistent-stm 0.1.0.1 → 0.1.0.2
raw patch · 3 files changed
+90/−3 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +1/−1
- README.md +87/−0
- persistent-stm.cabal +2/−2
CHANGELOG.md view
@@ -1,5 +1,5 @@ # Revision history for persistent-stm -## 0.1.0.0 -- 2022-07-21+## 0.1.0.2 -- 2022-07-21 * First version. Released on an unsuspecting world.
+ README.md view
@@ -0,0 +1,87 @@+# persistent-stm - STM transactions involving persistent storage++[](https://github.com/cdsmith/persistent-stm/actions/workflows/ci.yml)+[](https://hackage.haskell.org/package/persistent-stm)++Haskell's `STM` monad implements composable transactions on in-memory state,+offering atomicity, isolation, and consistency. However, they lack persistence,+so changes are not durable at all. This package adds a limited form of+persistence to the existing STM monad, allowing for transactions that include+writing values durably to external storage.++The persistence is limited in the following senses:++* First, it is only suitable for use by a single process at a time. It is not+ possible to access the storage from multiple processes at the same time,+ *even* *if* some of those processes are merely readers.+* While the view of data in memory is always consistent, the consistency of data+ on disk depends on the `Persistence` implementation, which you choose. The+ included implementation, `filePersistence`, does *not* guarantee that data+ will be in a consistent or readable state if the process is suddenly+ terminated with a power outage, system crash, etc. This can be fixed by using+ a `Persistence` implementation built on a transactional storage layer such as+ a database.++The persistence essentially works as a key-value store. The key is a `String`,+and the value can be of any type that implements `DBStorable`. The `DBStorable`+class works like `Binary` or other serialization classes, except that it's+designed to have access to the `DB` so that it can contain other `DBRef`s. This+way, at runtime, you can maintain complex data structures that point directly to+each other, but are persisted via their keys.++# Quick Start++A simple example of using `persistent-stm` follows:++```haskell+import PersistentSTM.DB++main :: IO ()+main = do+ persistence <- filePersistence "./my-data"+ withDB persistence $ \db -> do+ n <- atomically $ do+ ref <- getDBRef db "my-key"+ readDBRef ref >>= \case+ Nothing -> do+ writeDBRef ref 1+ return 1+ Just n -> do+ writeDBRef ref (n + 1)+ return (n + 1)+ putStrLn $ "Number of times program was run: " ++ show n+```++Here, `filePersistence` creates a `Persistence` implementation that stores data+in a directory called `./my-data` on disk. The `withDB` function brackets the+portion of code that uses the directory for storage. During the execution of+`withDB`, one can use `db` to read and write persistent values inside of STM+transactions. That is done using `getDBRef`, `readDBRef`, `writeDBRef`, and+`deleteDBRef`.++# FAQ++## Does this work reliably?++I'm publishing this now to get more feedback, but I am confident that within the+limitations described above, this is a correct implementation. Until there is a+broader community consensus, I'll still label this experimental.++## How does this compare with the TCache package?++The implementation here was inspired by TCache, and involves some similar ideas.+I was motivated to implement this package because of several details in which+use of TCache was hard to justify. These include:++* Playing too fast and loose with unsafe operations for my taste.+* Far too much use of global state and overlapping instances.+* Many more possible states making it hard to reason about the correctness of+ the implementation.+* Failure to build with newer GHC versions.++All things put together, I reached the conclusion that I could trust a new+implementation more than TCache.++Note that TCache has more features that this package. I don't intend to+implement features like triggers, indexes, and so on, all of which can be+implemented on top of the basic functionality in this package if desired.
persistent-stm.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: persistent-stm-version: 0.1.0.1+version: 0.1.0.2 synopsis: STM transactions involving persistent storage description: While Haskell's STM monad allows you to execute code transactionally, it does not allow you to persist the state@@ -15,7 +15,7 @@ author: Chris Smith <cdsmith@gmail.com> maintainer: Chris Smith <cdsmith@gmail.com> -extra-source-files: CHANGELOG.md+extra-source-files: CHANGELOG.md, README.md tested-with: GHC == 8.6.5 || == 8.8.4 || == 8.10.7 || == 9.0.1 || == 9.2.3