Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

[Features] Introducing a new EventBus CAP for eshop #970

Closed
wants to merge 17 commits into from

Conversation

yang-xiaodong
Copy link
Contributor

Hello :

I am the creator of CAP, and also a Microsoft MVP who loves open source very much. I saw eShop's EventBus a few months ago. It looks a bit simplistic and I found a lot of EventBus related in the issue list, and I answered some of them.

Last year, I opened an issue(#753) to ask if there was a plan to use a third-party event integration library, but I was frustrated that I didn't get more responses.

Recently, I had more time to do the extra works. I spent some time completing the CAP integration work for eshop and had already done the tests. He worked very well and saved a lot of code.

Here are the main changes I made:

  • Removed the EventBus building block
  • Replaced all project EventBus to CAP
  • Keep the original code structure as much as possible

Let me know if PR needs to be merged into a new feature branch.

I will reopen the issue(#753) so that we can discuss.

Looking forward to your feedback.

@mvelosop @CESARDELATORRE @eiximenis

@alexinea
Copy link

It is pleasure to hear that CAP has been integrated into the sample project eShopOnContainers. 😁

@mvelosop
Copy link
Collaborator

Hi @yang-xiaodong, Thanks for dedicating so much effort to get into the eShopOnContainers' internals.

There are several issues with this PR that deserve some special comments.

  • This is definitely a LARGE and impactful PR, not only by its sheer size (almost 140 files), but because it touches most, if not all, important microservices. It also affects the Microservices Guide/e-book.

  • Something that calls my attention is that you replaced the existing EventBus abstractions with yours. And that's the main cause for the size of the PR.

    I know I'm probably missing something important, but what's the reason for such a change? I mean, why not start with a concrete implementation using CAP? (BTW, I'm not suggesting you to do it).

  • Transaction atomicity and chained events handling (issue [BUG] There seems to be an atomicity issue while rising domain events in Ordering.Api #700 and related) had a significant overhaul recently, and one of the important changes was that the resulting integration events are only published if the domain events chain transaction completes successfully.

    It looks like this feature was removed, but then again, I just might have missed it, for I didn't get into all details. I focused mainly on Ordering.API.

  • There are also some seemingly minor changes to logging contexts, for no apparent reason, that actually break integration events correlation and traceability.

  • As a final comment, it looks like CAP hides away several details and completely replaces RabbitMQ and Azure ServiceBus implementations (you actually deleted them in this PR), which might be fine in another context, but I'm not sure this is a good thing given the purpose of eShopOnContainers.

Anyway, this just my (biased) opinion and the final decision is, of course, on @CESARDELATORRE .

Cheers.

cc/ @nishanil

@yang-xiaodong
Copy link
Contributor Author

Hello @mvelosop ,
Thanks for your reply, I am very happy to discuss some of your questions.


  • This is definitely a LARGE and impactful PR, not only by its sheer size (almost 140 files), but because it touches most, if not all, important microservices. It also affects the Microservices Guide/e-book.

Yes , this is really a very large PR, and I understand that the large PR is difficult to accept for the open source projects, but I think it is worth it.
I have seen most of the content in e-books, especially the outbox pattern description of EventBus and CAP is implemented this pattern.


  • Something that calls my attention is that you replaced the existing EventBus abstractions with yours. And that's the main cause for the size of the PR.

Yes, I removed the EventBus building blocks and replaced it with the abstraction provided by CAP. It is roughly divided into two steps :

  1. The event handler adds the [CapSubscribe] attribute to subscribe to specific events and inherits the ICapSubscribe interface so that the CAP can find it faster when it starts.
  2. Add the event handler class to the DI.

When the CAP startup, it generates the inbox table and the outbox table to the microservices database to ensure atomicity with the local transaction operations, and the CAP will take over the transaction object of the database context in the business operation to guarantee and store the atomicity of the event operation.

You can see here how to implement atomic operations between business code and storage events at here.

Of course, the integration events are only published if the domain events chain transaction completes successfully. Their implementation is slightly different for different databases. For example, in SQL Server, we use the Diagnostics feature provided by the SQL Client to detect the commit operation of the transaction and the code is here.


  • There are also some seemingly minor changes to logging contexts, for no apparent reason, that actually break integration events correlation and traceability.

Inside the CAP, there is a wrapper around the integration event transport object. We can track the event associations in the database based on the internal number, and CAP provides a Dashboard UI for user to search.


  • As a final comment, it looks like CAP hides away several details and completely replaces RabbitMQ and Azure ServiceBus implementations (you actually deleted them in this PR), which might be fine in another context, but I'm not sure this is a good thing given the purpose of eShopOnContainers.

Yes, CAP hides some details about the implementation of EventBus, and provide different message queues and different event storage extension packages.


In this PR, there are some integration events that are used the in-memory storage extension package., because these microservices use databases such as Redis that do not support ACID, obviously they can't guarantee atomicity.

MongoDB supports ACID transaction operations since version 4.0+, and CAP has provided support for it, but the MongoDB currently used by eshop is not a cluster, so it can not used and I use in-memory storage instead.

@paulvanbladel
Copy link

@yang-xiaodong @mvelosop
I didn't know CAP (well,... I know the CAP theorem) until I saw this PR.
I did today some monkey testing with a small sample with rabbitmq. So, I'm just sharing with you my findings.

  • configure cap with 2 apps pointing to same sql database for the outbox tables but in different schema's.
  • a simple event class with event handler
  • applied different disconnect scenarios, also when rabbitmq is offline.

CAP worked outstanding !
The current integration event handling solution in the eShopOnContainers is good for learning purposes but very imcomplete (the current version has serious problem with disconnect scenarios). CAP would definitely bring things to yet another level.

@CESARDELATORRE
Copy link
Collaborator

Adding @eiximenis and @unaizorrilla so they can also evaluate and provide feedback.

I think it might not make sense to put CAP under our EventBus abstractions since CAP already has its opinionated interfaces offering further features and also works on top of Azure Service Bus, RabbitMQ and Kafka. It wouldn't make sense to have two layers of abstractions, right?

However, eShopOnContainers aims to provide patterns implementation for learning purposes. Being prescriptive with CAP or any other Service Bus is a different thing..

Why CAP and not NServiceBus, MassTranssit or any other Service Bus approach?

@yang-xiaodong - What you could do is to fork eShopOnContainers and have that implementation in a different repo, such as the NServiceBus eShopOnContainers implementation here:

https://github.com/Particular/eShopOnContainers

So we could also point to your CAP implementation from the documentation and the GitHub repo.
That way you can maintain it up-to-date related to CAP future versions, etc.

Thoughts?

@yang-xiaodong
Copy link
Contributor Author

@CESARDELATORRE Thanks for your reply, I agree with you about that current patterns implementation for learning purpose.

I will fork the eShopOnContainers and provide EventBus integration with CAP. In fact, it is the repository pointed to by the current PR and I have changed the default branch to CAP.

Should I submit a PR that modifies README to point to my repository? Can accept?

@CESARDELATORRE
Copy link
Collaborator

CESARDELATORRE commented Mar 21, 2019 via email

@yang-xiaodong
Copy link
Contributor Author

Hello @CESARDELATORRE,

I have submitted a PR (#975) about adding EventBus note to the README. I will complete the description in my eShopOnContainers branch later.

Thanks ! :)

@mvelosop
Copy link
Collaborator

Hi @yang-xiaodong, I'm closing this PR now, just waiting for your update to PR #975

@mvelosop mvelosop closed this Mar 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants