GregoryConrad / rearch-rs

Re-imagined approach to application design and architecture

Home Page:https://crates.io/crates/rearch

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Consider removing `CapsuleData: Clone` requirement

GregoryConrad opened this issue · comments

Spun out of #11. If we go down this route, which I am inclined to do:

  1. Introduce a .as_ref() on CapsuleReader. So we can do get(xyz_capsule) for ease of use when xyz_capsule::Data: Clone, but also provide get.as_ref(xyz_capsule) when it doesn't have Clone and/or for performance reasons (to skip the clone()). I think this API is the best of both worlds.
  2. I do not think a Container::read_ref() would be possible, at least to return a &T directly. This is because it would internally need a read txn, and that read txn would be dropped when read_ref() returns.
    a. Easy fix: create new ContainerReadRefGuard (like mutexes use) that impl Deref and holds onto the read txn.
    b. Alternatively, we could expose a .write_txn() and .read_txn() on the container, but this would also require a way to downgrade/get a read snapshot from the write txn (use case: user needs to ensure some data is in the container when they read it, so they 1. try a read txn, but data isn't there, so they 2. spin up write to init capsule, and finally 3. downgrade into a read so they can continue to access that data later on)

I am inclined to go with 2a because:

  • It is more ergonomic than manually using transactions
  • Will prevent a user from holding onto a write txn for any period of time (which will stall other writers)
  • We can always add 2b later if there is demand for such a feature, but we should try to add some safety guards in such a situation to prevent a write txn from being open forever

I was having difficulty implementing a Container::read_ref due to transaction lifetimes, but that alone isn't enough to stop me from releasing this feature.

Issue: snapshots have a lifetime dependency on their associated read/write txn, which will go out of scope when the with_txn block is up.
We can work around this for read txns by just giving our new struct returned from read_ref its own copy of the read txn. However, this won't work for write txns since keeping the write txn open will hold the mutex locks, which is unacceptable.
Thus, we would likely need some specialized support from concread in order to support Container::read_ref (we need the ability to "downgrade" a write txn into a read txn, or obtain a snapshot that will outlive its write txn).