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

post: Introducing Jaiminho, an implementation of the Transactional Outbox Pattern for Django #71

Merged
merged 9 commits into from
Mar 2, 2023

Conversation

rfzanetti
Copy link
Contributor

No description provided.

@netlify
Copy link

netlify bot commented Sep 14, 2022

Deploy Preview for loadsmart-engineering ready!

Name Link
🔨 Latest commit d8fa7ec
🔍 Latest deploy log https://app.netlify.com/sites/loadsmart-engineering/deploys/6400927f53c7fc000799f64a
😎 Deploy Preview https://deploy-preview-71--loadsmart-engineering.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.


The Event Relaying Command will query the database for all events that were not sent in a given timebox and will try to re-send them using the original method, message and kwargs. Note that if the event relay runs after a deploy that changed or removed the original method, it will not be able to re-send the failed events and they will have to be dealt with manually. Also, the `DELETE_AFTER_SEND` configuration also applies to this command.

Tip: Schedule this command to be regularly executed and Jaiminho will ensure all failed events are re-sent.

Choose a reason for hiding this comment

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

Would be nice to include the consumer mode when the relayer runs forever (no scheduling)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! Can you check the new text to see if it's well explained?

Copy link

@antunesleo antunesleo left a comment

Choose a reason for hiding this comment

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

Good stuff, awesome article! very well explained by the way

I've left a couple of minor comments, check it out


# How Jaiminho works

With the default configuration, when you add the `@save_to_outbox` decorator to a method, whenever it is called and raises an exception, Jaiminho will create a database entry storing:

Choose a reason for hiding this comment

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

If we use the keep order option, we save it always and store it for sending it in order. Right @antunesleo ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah! With the keep order option, the persist all events is mandatory. It is explained on the Persist all events subsection on the additional settings section.

---
title: Introducing Jaiminho, an implementation of the Transactional Outbox Pattern for Django
author: Rafael Zanetti
twitter: LoadsmartEng
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you have a Twitter account @rfzanetti ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do, but it has too much dumb stuff and not to much tech stuff haha I could also create an account just to link it here, what do you suggest?

@rfzanetti rfzanetti marked this pull request as ready for review November 4, 2022 22:32
Copy link
Contributor

@gustahrodrigues gustahrodrigues left a comment

Choose a reason for hiding this comment

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

🚀

content/posts/2022-09-14-introducing-jaiminho/index.md Outdated Show resolved Hide resolved
}
```

4) Add the `@save_to_outbox` decorator to any method responsible for communicating with external systems (brokers, external APIs, etc):
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: I would give more colors around save_to_outbox_stream as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the post is already a bit crowded with a lot of the configuration options, so maybe might be worth leaving it just on the documentation. What do you think?

comments: true
---

At Loadsmart, many of our services are organized within an event-driven architecture and face some usual challenges that come with such an architecture. One of them is **dual writes**, which happens when an application has to change data on two different places. A common example of dual writes is an application that needs to store data on a database and notify that change by emitting an event which may be consumed by different services. The inherent issue with this scenario is that if one of these two operations fails, the producer and consumer applications will have data inconsistencies. If we choose to write the change to the database first and then notify the event, in the case of a notification failure the database would have the updated data and the consumer wouldn’t. If we reverse it (i.e. notifying first and then storing), a failure when committing the transaction in the database would cause the consumer receiving data that isn’t on the application database.

Choose a reason for hiding this comment

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

What about linking some material about dual writes ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I feel it's a bit of overkill...I think that the main audience would be people that already are experienced with this issue (and hopefully are considering adding jaiminho to their projects? 😄), but for other people who don't know what that is, the explanations on the post are enough.

What do you think?


At Loadsmart, many of our services are organized within an event-driven architecture and face some usual challenges that come with such an architecture. One of them is **dual writes**, which happens when an application has to change data on two different places. A common example of dual writes is an application that needs to store data on a database and notify that change by emitting an event which may be consumed by different services. The inherent issue with this scenario is that if one of these two operations fails, the producer and consumer applications will have data inconsistencies. If we choose to write the change to the database first and then notify the event, in the case of a notification failure the database would have the updated data and the consumer wouldn’t. If we reverse it (i.e. notifying first and then storing), a failure when committing the transaction in the database would cause the consumer receiving data that isn’t on the application database.

There are well-known methods to deal with such issues, and we chose to apply the transactional outbox pattern. Since we couldn’t find any related solution on [Django community](https://djangopackages.org/search/?q=outbox), we decided to implement an open-source library called [Jaiminho](https://github.com/loadsmart/jaiminho), which is a broker agnostic implementation of the outbox pattern.

Choose a reason for hiding this comment

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

Same, linking something digging deeper into Transaction Outbox Pattern

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same thing as above

comments: true
---

At Loadsmart, many of our services are organized within an event-driven architecture and face some usual challenges that come with such an architecture. One of them is **dual writes**, which happens when an application has to change data on two different places. A common example of dual writes is an application that needs to store data on a database and notify that change by emitting an event which may be consumed by different services. The inherent issue with this scenario is that if one of these two operations fails, the producer and consumer applications will have data inconsistencies. If we choose to write the change to the database first and then notify the event, in the case of a notification failure the database would have the updated data and the consumer wouldn’t. If we reverse it (i.e. notifying first and then storing), a failure when committing the transaction in the database would cause the consumer receiving data that isn’t on the application database.
Copy link

@antunesleo antunesleo Feb 28, 2023

Choose a reason for hiding this comment

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

I would change when an application has to change to when an application has to write

Copy link

@antunesleo antunesleo left a comment

Choose a reason for hiding this comment

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

LGTM

I've left only one minor comment

@gustahrodrigues gustahrodrigues merged commit 312a9a9 into main Mar 2, 2023
@peril-loadsmart peril-loadsmart bot deleted the wg-outbox-post branch March 2, 2023 12:20
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

Successfully merging this pull request may close these issues.

6 participants