NFIBrokerage / spear

A sharp EventStoreDB v20+ client backed by Mint :yum:

Home Page:https://hex.pm/packages/spear

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

the :from option is actually inclusive

the-mikedavis opened this issue · comments

testing out with volley, ran into that events specified in :from are returned by Spear.read_stream/3

iirc the documentation for :from says that this is exclusive which is not the case

So it actually appears as though subscriptions are exclusive but reads only through read_stream/3 are inclusive:

Subscriptions:

iex> Stream.iterate(0, &(&1 + 1)) |> Stream.map(&Spear.Event.new("asdf", &1)) |> Stream.take(3) |> Spear.append(conn, "clusivity_test", expect: :empty)
:ok
iex> {:ok, start_sub} = Spear.subscribe(conn, self(), "clusivity_test", from: :start)
{:ok, #Reference<0.3024145066.3358851076.197200>}
iex> event = receive(do: (event -> event))
%Spear.Event{body: 0, ..}
iex> flush
%Spear.Event{body: 1, ..}
%Spear.Event{body: 2, ..}
iex> Spear.cancel_subscription(conn, start_sub)
:ok
iex> 
iex> {:ok, from_0_sub} = Spear.subscribe(conn, self(), "clusivity_test", from: event)
{:ok, #Reference<0.3024145066.3358851073.196545>}
iex> flush
# n.b. body 0 is not sent to the subscriber, so it's exclusive
%Spear.Event{body: 1, ..}
%Spear.Event{body: 2, ..}

Reads:

iex> [event] = Spear.stream!(conn, "clusivity_test", from: :start) |> Enum.take(1)
%Spear.Event{body: 0, ..}
iex> Spear.stream!(conn, "clusivity_test", from: event) |> Enum.take(1)
# n.b. exclusive?!
%Spear.Event{body: 1, ..}
iex> {:ok, events} = Spear.read_stream(conn, "clusivity_test", from: event)
iex> events |> Enum.take(1)
# n.b. inclusive, matches ^event
%Spear.Event{body: 0, ..}

So it appears as though this is inconsistent between stream!/3 and read_stream/3.

two paths forward:

  • make stream!/3 inclusive
  • make read_stream/3 exclusive

while it may be more consistent with subscriptions to make read_stream/3 exclusive, I lean towards the first option as you can always Stream.drop(events, 1) to get rid of the first event but you can't 'go back in time' to find the event provided (considering that some consumer may rely on the behavior of inclusivity to read that event

as long as the documentation is specific, I don't think it actually matters which one we go with

playing around with the nodejs client looks like inclusive is a consistent choice