Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EmptyStream value inconsistency vs EventStore #332

Open
bartelink opened this issue Nov 2, 2019 · 5 comments
Open

EmptyStream value inconsistency vs EventStore #332

bartelink opened this issue Nov 2, 2019 · 5 comments

Comments

@bartelink
Copy link
Contributor

In the course of jet/equinox#168, I tripped up during some direct porting of a library that wraps EventStore. The item in question is the naming and values of the Version special values (this applies in 1.2.0-beta4/6)

  1. ES has deprecated EmptyStream in favour of NoStream https://github.com/EventStore/EventStore/blob/03435307176cc7118a0d76657df9f87a47eb8c00/src/EventStore.ClientAPI/ExpectedVersion.cs#L27
  2. SSS still has both
    public const int EmptyStream = -1;
  3. BUT the SSS NoStream is -3 and the ES one is -1
    This happens to cause me a problem as I need the value to be -1 for some formulae to not be off by 2...

I've special cased things, but ideally the names or values would either converge or have a name that makes you think ?

related #331

@bartelink
Copy link
Contributor Author

Then other inconsistency to note is that ES lib versions >=4 use a Long for the index; perhaps this may offer a way to make any change evident?

@thefringeninja
Copy link
Member

thefringeninja commented Nov 4, 2019 via email

@bartelink
Copy link
Contributor Author

bartelink commented Nov 4, 2019

TL;DR my problem is that the API is surprising and one can easily make a mistake when porting from ES to SSS. Yes, I know most go the other direction, but that really isn't the point. I can't think of a way to express "you're not making any sense" without pretty much regurgitating the above

Your answer still leaves my concerns as described above unsolved:

  • (probably too late to change but) avoidable differences in value of the same constant between SSS and ES which mean more special casing vs the ES API because math: [the ES value] of -1 actually makes sense if we are to represent an ExpectedVersion as a Version Number - i.e. when we have 0 events, the version is -1, when we have 2, the value is 1. The -1 works as a Null Object Pattern in that you can use that value as the version value and it is logically consistent with how versions other than that for an empty stream work,
  • (this is fixable) the one that ES and SSS have in common is deprecated in ES
  • the types between ES and SSS are Int32 vs Int64 (suggesting SSS should go int64 for simiplicity)

An example of something that would solve the problem is to deprecate EmptyStream and NoStream in SSS and replace with something new which removes the two problems, viz:

  1. the SSS value of NoStream is different to the ES one
  2. the maths doesnt work if NoStream <> -1

@thefringeninja
Copy link
Member

thefringeninja commented Nov 4, 2019 via email

@bartelink
Copy link
Contributor Author

Right - I agree that's a much clearer way to model it; thanks for taking the time to make it concrete for me

If SSS v2 was to present type ExpectedVersion = Revision of int64 | NoStream | Any | StreamExists, then I'd be forced to pick one. However AIUI, if I want to say "The event I'm writing better be event number 0", I still need to supply an ExpectedVersion value which is Revision -1

Right now, SSS requires an Int32, and the correct value for "I am expecting that I am writing the first event" is -1.

IME people like representing ExpectedVersion as an integer and it works well for a heck of a lot of cases. If we didnt have the legacy of ES having EmptyStream and NoStream being -1 and aligning with the general Revision number value, then there is no problem, but I feel too much logic in the field leans on this.

My problem/the inconsistency I'm calling out:

a) the current ES way of doing that:

  • was use EmptyStream (but that's deprecated)
  • is use NoStream (which is a magic value of -1)
  • will be use Revision -1 (where will I get the -1 or is NoStream the correct equivalent value?)
  • internally make a DU of type ExpectedVersion = EmptyStream | Revision of ver: int64 and map that to ExpectedVersion.NoStream and ver respectively

b) the SSS ways of doing that:

  • use EmptyStream - the constant is -1 so it logically works as a Null Object Pattern value but EventStore is not using that anymore
  • DO NOT use NoStream like you would with ES as the (magic value for that is -3)
  • hard code or internally make a DU of type ExpectedVersion = EmptyStream | Revision of ver: int64 and map that to -1 and (Int32) ver respectively

My bottom line is that

  1. I'm only interested in "I am writing event 0` and I am writing another event
  2. I need a constant for the first case
  3. the correct constant has a different name in SSS (use NoStream as EmptyStream is deprecated) vs ES (use NoStream)
  4. the common constant (NoStream) has a surprising and different value in SSS (-3) which a) broke my port b) will require me to put comments in the impl now I've discovered that as there is no reliable way in which I can use a constant and have the code read the same way in SSS and ES

To cut a long story short: if some future SSS v2 design can force people away from this potential bug and align with an ES v6 API, that'd be great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants