Closed sascha-wolf closed 3 years ago
Hi @sascha-wolf,
The library was originally designed to support any arbitrary delta_crdt, but over the course of time evolved to do just this one CRDT more effectively (including using MerkleMap for efficient propagation). So that's the reason for the odd layout of the internals.
I would accept a PR that adds a read/3
. I think the following signatures make the most sense:
def read(crdt, args, timeout \\ 5000) when is_list(args)
def read(crdt, timeout \\ 5000)
I'm not sure about making []
synonymous with all keys
, I think if you submit an empty list of keys we should short-circuit and return an empty list back.
Thanks for the super quick reply @derekkraan!
My train of thought on read(crdt, [])
reading everything was to stay as close as possible to the semantics of mutate
, that is, the arguments get used in an apply
call.
So for read
that would basically boil down to this code in casual_crdt.ex
:
def handle_call({:read, args}, _from, state) do
{:reply, apply(state.crdt_module, :read, [state.crdt_state | args]), state}
end
So read(crdt, [])
would result in calling AWLWWMap.read(state)
while read(crdt, ["foo"])
would call AWLWWMap.read(crdt, "foo")
. If at some point something other than AWLWWMap
comes along which accepts more than a single additional argument on read
the DeltaCrdt
API would be able to handle this.
I understand your train of thought, but at this point I'm not sure there will ever be anything other than AWLWWMap
, so I'm perfectly ok with an API that more closely reflects the semantics of AWLWWMap
. I am also planning to deprecate mutate
at some point and add functions that are more reflective of a map in the future, to make the API a bit easier, since supporting multiple types of CRDT is no longer a design goal of this library.
Ah, I see. In that case I'll open a PR based on your suggestion. 🙂
First things first: I've went through the source code and noticed that the
AWLWWMap
not only offersread/1
to get the whole map but alsoread/2
to a subset of keys.I'd like to open a PR which uses
read/2
to read a single value from theAWLWWMap
, similar toMap.get/2
. But from where I'm standing I'm under the impressions that theDeltaCrdt
module has been explicitly designed to not assume any kind of particular data structure "under the hood", which means that aDeltaCrdt.get/2
would break that assumption.As such I'd like to ask: how could an API look like which allows to use a "more sophisticated"
read
operation on the underlying data structure, such asread/2
onAWLWWMap
?What I imagine could work is something like this:
And adjusting the
casual_crdt
GenServer
to accept a{:read, args}
message. This in turn would keep the previous API intact - making for a non breaking change - but allow for the following API usage:Any thoughts on this?