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

Event Store v8 #354

Merged
merged 20 commits into from
Dec 30, 2018
Merged

Event Store v8 #354

merged 20 commits into from
Dec 30, 2018

Conversation

prolic
Copy link
Member

@prolic prolic commented Dec 22, 2018

Common classes and interfaces for Event Store v8

This will be adopted by

Merry X-Mas

Edit:
Should we remove the Exception suffix?

@prolic prolic requested review from sandrokeil, codeliner and a team December 22, 2018 17:02
@codeliner
Copy link
Member

Cool! I'll review after X-Mas, though.
Merry X-Mas @prolic 🎄 🎅

Copy link
Contributor

@danizord danizord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! It seems that v8 brings a lot of new features and is way more robust :)

Just some points:

  • I'm wondering if this abstraction layer is not too big for now. I mean, some features like subscription statistics and user management will be a bit hard to implement in (No-)SQL implementations. I'd suggest to reduce this surface API to the minimum viable for the first 8.x release and start adding new features in next minor versions.
  • Having separate sync and async APIs seems to hurt readability and maintainability. Why not always return promises even when using sync connections?
  • For (No-)SQL, I think it will be easier to have different API for projections instead of parsing and interpreting JS code in PHP :P
  • How can the community help to write the new implementations? How about creating some issues as detailed tasks, so that we can parallelize some work? :)

Again, thanks for the great work. Merry Christmas!

README.md Outdated Show resolved Hide resolved
src/AsyncEventStoreCatchUpSubscription.php Show resolved Hide resolved
*/
public function fail(
ResolvedEvent $event,
PersistentSubscriptionNakEventAction $action,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, I love it! 👏👏


use Throwable;

interface AsyncPersistentSubscriptionDropped
Copy link
Contributor

@danizord danizord Dec 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about suffixing those with Handler?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like that idea. Makes the names even longer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhmm, I don't care about the length. This name is failing to express the purpose of this class :/

return $this->verboseLogging;
}

public function enableVerboseLogging(): self
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function enableVerboseLogging(): self
public function withEnabledVerboseLogging(): self

To clarify immutability?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't like it.

return $this->eventType;
}

public function isJson(): bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about creating a JsonEventData class and determine it by type? Also, it could have some named constructor that receives data and metadata as array and encodes them internally.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that flag is very important for (No-)Sql implementations later. It's also the same in the original Event Store .NET Client. You can create a JsonEventData class in userland if you want to.

'Success' => 0,
'NotFound' => 1,
'NoStream' => 2,
'StreamDeleted' => 3,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can reuse the constants here as value (same for other enum classes).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was auto-generated by prolic/fpp. We can change that, of course, but for now I have more important things to do. You can send a PR though, would love it.

// The stream being written to should not yet exist. If it does exist treat that as a concurrency problem.
public const NO_STREAM = -1;
// The stream should exist and should be empty. If it does not exist or is not empty treat that as a concurrency problem.
public const EMPTY_STREAM = -1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the comment, it probably should not have the same value as NO_STREAM :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it should! I know it's weird, but that's the way it is. I can't change the implementation details of the original Event Store.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments tell that the event store behaves differently in each case, but how can it identify which one is being used? Maybe the comments are wrong then.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danizord You only care about the constant name. What ever the value might be, it's not your problem to deal with.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem, just found this bug and wanted to help. It's impossible to branch behavior based on 2 flags that have the same value :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot change the values at all, really sorry.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, so you'll probably need to change the comments.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why that? The comment declares exactly when to use which constant. Even if the value is the same, so what?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also declares how the event store behaves in each case: NO_STREAM throws exception if the stream exists, while EMPTY_STREAM throws if the stream does not exist.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR is welcome.


public static function create(): PersistentSubscriptionSettingsBuilder
{
return new PersistentSubscriptionSettingsBuilder(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having builders, I think it would be easier to have empty constructor, put these default values inline in property declaration and provide with* methods.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't like that idea.

danizord and others added 2 commits December 25, 2018 15:27
Co-Authored-By: prolic <saschaprolic@googlemail.com>
@prolic
Copy link
Member Author

prolic commented Dec 25, 2018

Just some points:

  • I'm wondering if this abstraction layer is not too big for now. I mean, some features like subscription statistics and user management will be a bit hard to implement in (No-)SQL implementations. I'd suggest to reduce this surface API to the minimum viable for the first 8.x release and start adding new features in next minor versions.

For SQL implementations we can simply not implement the user management API is a first release, if it's too time consuming. However the interface exists, no matter if you implement it or not.

  • Having separate sync and async APIs seems to hurt readability and maintainability. Why not always return promises even when using sync connections?

This would give the false impression that all implementations are async, when they are clearly not. As of now there is for example no async driver for mongodb, except some very old experimental one.

  • For (No-)SQL, I think it will be easier to have different API for projections instead of parsing and interpreting JS code in PHP :P

Yes, that's correct, that's why we will be using PHP code instead.

  • How can the community help to write the new implementations? How about creating some issues as detailed tasks, so that we can parallelize some work? :)

I'm working on this since April this year and did everything alone, except for some reviews and bug reports from some people (thanks guys, you know who you are!). I also created most of the v7 implementation on my own. So realistically I don't expect much contribution from the community and therefore the extra work of writing lots of tickets that I do all by myself doesn't justify.

However if you or anyone else is willing to help out, hit me in the prooph-chat and we can discuss how you can help and I can give explanations on how some implementation details have to look like.

As of now, I like to finish the event-store-client and event-store-http-client first, before I start on the SQL implementations. I use them both already in production.

@prolic prolic merged commit 523a774 into master Dec 30, 2018
@prolic prolic deleted the initial_v8 branch December 30, 2018 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants