From e920261463e96d7aaa463fb893b76e2887002211 Mon Sep 17 00:00:00 2001 From: Rafael Zanetti Date: Wed, 14 Sep 2022 19:50:56 -0300 Subject: [PATCH 1/9] Adding post for Jaiminho, an implementation of the transactional outbox pattern --- .../2022-09-14-introducing-jaiminho/index.md | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 content/posts/2022-09-14-introducing-jaiminho/index.md diff --git a/content/posts/2022-09-14-introducing-jaiminho/index.md b/content/posts/2022-09-14-introducing-jaiminho/index.md new file mode 100644 index 0000000..bca141d --- /dev/null +++ b/content/posts/2022-09-14-introducing-jaiminho/index.md @@ -0,0 +1,136 @@ +--- +title: Introducing Jaiminho, an implementation of the Transactional Outbox Pattern for Django +author: Rafael Zanetti +twitter: LoadsmartEng +layout: post +lang: en +path: /blog/introducing-jaiminho +date: 2022-09-14 +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, because the consumer never received the event informing the database change. + +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. + + +# The Transactional outbox pattern + +For simplicity purposes, let’s assume the common case of an application that has to save data to a database and notify it to an event stream. The idea behind the transactional outbox pattern is combining both writes into a single atomic transaction, which guarantees that if one of them fails, the entire transaction fails, avoiding inconsistent scenarios; in this case, it means that if a record is persisted into the database, it is guaranteed to be notified to the stream. The pattern achieves this goal by introducing two concepts: + +- Outbox table + +When storing a record to the database, the corresponding event should be persisted into an outbox table, and both inserts should be in the same transaction. With this strategy we can leverage the atomicity property of relational databases transactions to ensure either both or no inserts will be successful. + +- Message relay + +The outbox table is guaranteed to have all events that should be notified, so we just have to ensure that they are really sent. This responsibility goes to the message relay, which will publish all events in the table to the stream and mark them as sent. +Note: Since the message relay has to send an event and then mark it as sent, that characterizes another dual write, because if the relay fails to update the status after sending the event, it will be sent again on the next execution. So, to ensure no duplicated events are delivered, the message consumers must implement idempotence on their side. + +# Using Jaiminho in your project + +To add Jaiminho to your project, you have to: + +1) Install it: + +```console +python -m pip install jaiminho +``` + +2) Add it to the Django project’s `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + "django.contrib.auth", + "django.contrib.contenttypes", + ... + ... + ... + "jaiminho" +] +``` + +3) Configure the options in the project’s Django `settings.py`: + +```python +JAIMINHO_CONFIG = { + "PERSIST_ALL_EVENTS": False, + "DELETE_AFTER_SEND": True, + "PUBLISH_STRATEGY: "publish-on-commit" + } +``` + +4) Add the `@save_to_outbox` decorator to any method responsible for communicating with external systems (brokers, external APIs, etc): + +```python +from jaiminho.send import save_to_outbox + +@save_to_outbox +def any_external_call(**kwargs): + # do something + return +``` + + +# 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: + +- The message that is being sent to the external system, serialized into bytes +- The method that was used for sending that message +- The extra kwargs used to call the method + +This data will allow for the message to be sent again using the original method, message and kwargs. Also, at the end of the decorated method a Django signal will be sent to indicate the event success or failure. + +Since the message and kwargs are serialized into bytes, any type of message is supported. For example, in Loadsmart we work with JSON and Protobuf messages, and both are using Jaiminho with no need of special configurations. + +## Publish strategies + +With Jaiminho, you can choose between the following two publish strategies, using the `PUBLISH_STRATEGY` configuration: + +### Keep Order +This strategy is similar to the transactional outbox [described by Chris Richardson](https://microservices.io/patterns/data/transactional-outbox.html). The decorated function intercepts the function call and saves it on local DB to be executed later. A separate event relayer will keep polling local DB and executing those functions in the same order it was stored. +Be careful with this approach, **if any execution fails, the relayer will get stuck**. Otherwise, it would not possible to guarantee delivery order. + +### Publish on commit + +This strategy will always execute the decorated function after the current transaction commit. With this approach, we don’t depend on an event relayer to execute the decorated function and deliver the message. Failed items will only be executed through the relayer. Although we can decrease the delay to execute the decorated function with this approach, **we cannot guarantee delivery order**. + +## Additional settings + +Besides the publish strategies, there are two other options that can be configured: + +### PERSIST_ALL_EVENTS + +While the default behavior of Jaiminho makes losing an event less likely, it still has a point of failure: if the notifying method fails and Jaiminho receives an error trying to store the database entry, the event will be lost. In order to avoid this possibility, the `PERSIST_ALL_EVENTS` configuration can be set to True, which will save the database entry *before* trying to notify the event. In this case, the notifying method will be called when the database transaction is committed, which will ensure that the event is persisted. This is not applicable when the publish strategy is **Keep order**, because all the messages must be stored to achieve this strategy. + +### DELETE_AFTER_SEND + +The `PERSIST_ALL_EVENTS` configuration can be combined with the `DELETE_AFTER_SEND` one. If `DELETE_AFTER_SEND` is activated, after a successful notifying of the event, the persisted database entry will be deleted, in order to make sure Jaiminho will not store successfully sent events. + +You may be asking: why isn’t the `PERSIST_ALL_EVENTS` configuration the default behavior of Jaiminho? The reason behind it is performance. For each event sent, the activation of this setting will cause two extra database operations (one insertion and one deletion), which can be a lot for use cases where there is a large number of events being sent. So, it’s up to your use case and you to decide whether you prefer the performance of just going to the database if something fails or the consistency guarantee of not losing any events. + +## Django Commands + +Jaiminho comes with two Django Commands that can be useful: + +### Event Relaying + +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. + +### Event Cleaning + +The Event Cleaning Command will query the database for all events that were successfully re-sent in a given timebox and will delete them from the database in order to limit storage using for old events. + +## Triggered signals + +Jaiminho emits two Django signals, which can be used, for example, for collecting metrics: + +- `event_publish` : emitted when an event is successfully sent +- `event_failed_to_published` : emitted when an event failed to be sent + +# Final remarks + +If you are interested in learning more, there is a detailed documentation on the [GitHub repository](https://github.com/loadsmart/jaiminho). Also, contributions are more than welcome! Feel free to contribute if you find any bugs or have any suggestions. From 4a61ef9b07e8f3783d2f223ee7d9bec3f944ad2d Mon Sep 17 00:00:00 2001 From: Rafael Zanetti Date: Fri, 4 Nov 2022 19:19:01 -0300 Subject: [PATCH 2/9] applying PR comments on jaiminho post --- .../2022-09-14-introducing-jaiminho/index.md | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/content/posts/2022-09-14-introducing-jaiminho/index.md b/content/posts/2022-09-14-introducing-jaiminho/index.md index bca141d..ce3a222 100644 --- a/content/posts/2022-09-14-introducing-jaiminho/index.md +++ b/content/posts/2022-09-14-introducing-jaiminho/index.md @@ -5,11 +5,11 @@ twitter: LoadsmartEng layout: post lang: en path: /blog/introducing-jaiminho -date: 2022-09-14 +date: 2022-11-25 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, because the consumer never received the event informing the database change. +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. @@ -20,12 +20,12 @@ For simplicity purposes, let’s assume the common case of an application that h - Outbox table -When storing a record to the database, the corresponding event should be persisted into an outbox table, and both inserts should be in the same transaction. With this strategy we can leverage the atomicity property of relational databases transactions to ensure either both or no inserts will be successful. +When storing a record to the database, the corresponding event should be persisted into an outbox table, and both operations should be in the same transaction. With this strategy we can leverage the atomicity property of relational databases transactions to ensure either both or no inserts will be successful. - Message relay The outbox table is guaranteed to have all events that should be notified, so we just have to ensure that they are really sent. This responsibility goes to the message relay, which will publish all events in the table to the stream and mark them as sent. -Note: Since the message relay has to send an event and then mark it as sent, that characterizes another dual write, because if the relay fails to update the status after sending the event, it will be sent again on the next execution. So, to ensure no duplicated events are delivered, the message consumers must implement idempotence on their side. +Note: Since the message relay has to send an event and then mark it as sent, that characterizes another dual write, because if the relay fails to update the status after sending the event, it will be sent again on the next execution. So, to ensure no duplicated events are consumed, the message consumers must implement idempotence on their side. # Using Jaiminho in your project @@ -56,7 +56,7 @@ INSTALLED_APPS = [ JAIMINHO_CONFIG = { "PERSIST_ALL_EVENTS": False, "DELETE_AFTER_SEND": True, - "PUBLISH_STRATEGY: "publish-on-commit" + "PUBLISH_STRATEGY: "keep-order" } ``` @@ -100,15 +100,15 @@ This strategy will always execute the decorated function after the current trans Besides the publish strategies, there are two other options that can be configured: -### PERSIST_ALL_EVENTS +### Persist all events While the default behavior of Jaiminho makes losing an event less likely, it still has a point of failure: if the notifying method fails and Jaiminho receives an error trying to store the database entry, the event will be lost. In order to avoid this possibility, the `PERSIST_ALL_EVENTS` configuration can be set to True, which will save the database entry *before* trying to notify the event. In this case, the notifying method will be called when the database transaction is committed, which will ensure that the event is persisted. This is not applicable when the publish strategy is **Keep order**, because all the messages must be stored to achieve this strategy. -### DELETE_AFTER_SEND +### Delete after send The `PERSIST_ALL_EVENTS` configuration can be combined with the `DELETE_AFTER_SEND` one. If `DELETE_AFTER_SEND` is activated, after a successful notifying of the event, the persisted database entry will be deleted, in order to make sure Jaiminho will not store successfully sent events. -You may be asking: why isn’t the `PERSIST_ALL_EVENTS` configuration the default behavior of Jaiminho? The reason behind it is performance. For each event sent, the activation of this setting will cause two extra database operations (one insertion and one deletion), which can be a lot for use cases where there is a large number of events being sent. So, it’s up to your use case and you to decide whether you prefer the performance of just going to the database if something fails or the consistency guarantee of not losing any events. +You might be wondering: why isn’t the `PERSIST_ALL_EVENTS` configuration the default behavior of Jaiminho? The reason behind it is performance. For each event sent, the activation of this setting will cause two extra database operations (one insertion and one deletion), which can be a lot for use cases where there is a large number of events being sent. So, it’s up to your use case and you to decide whether you prefer the performance of just going to the database if something fails or the consistency guarantee of not losing any events. ## Django Commands @@ -116,9 +116,12 @@ Jaiminho comes with two Django Commands that can be useful: ### Event Relaying -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. +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. +To ensure all failed events are re-sent by Jaiminho, you have two options with the Event Relaying command: + +- Schedule it to be regularly executed (with a cronjob, for example) +- Run it in a loop using the `--run_in_loop` and `--loop_interval` flags ### Event Cleaning From af6e24d3f820aa6a7677ec078f36d0d4d4a9618e Mon Sep 17 00:00:00 2001 From: Rafael Zanetti Date: Tue, 8 Nov 2022 17:52:38 -0300 Subject: [PATCH 3/9] applying pr suggestions --- .../2022-09-14-introducing-jaiminho/index.md | 98 ++++++++++--------- 1 file changed, 53 insertions(+), 45 deletions(-) diff --git a/content/posts/2022-09-14-introducing-jaiminho/index.md b/content/posts/2022-09-14-introducing-jaiminho/index.md index ce3a222..9f22e7a 100644 --- a/content/posts/2022-09-14-introducing-jaiminho/index.md +++ b/content/posts/2022-09-14-introducing-jaiminho/index.md @@ -27,50 +27,6 @@ When storing a record to the database, the corresponding event should be persist The outbox table is guaranteed to have all events that should be notified, so we just have to ensure that they are really sent. This responsibility goes to the message relay, which will publish all events in the table to the stream and mark them as sent. Note: Since the message relay has to send an event and then mark it as sent, that characterizes another dual write, because if the relay fails to update the status after sending the event, it will be sent again on the next execution. So, to ensure no duplicated events are consumed, the message consumers must implement idempotence on their side. -# Using Jaiminho in your project - -To add Jaiminho to your project, you have to: - -1) Install it: - -```console -python -m pip install jaiminho -``` - -2) Add it to the Django project’s `INSTALLED_APPS`: - -```python -INSTALLED_APPS = [ - "django.contrib.auth", - "django.contrib.contenttypes", - ... - ... - ... - "jaiminho" -] -``` - -3) Configure the options in the project’s Django `settings.py`: - -```python -JAIMINHO_CONFIG = { - "PERSIST_ALL_EVENTS": False, - "DELETE_AFTER_SEND": True, - "PUBLISH_STRATEGY: "keep-order" - } -``` - -4) Add the `@save_to_outbox` decorator to any method responsible for communicating with external systems (brokers, external APIs, etc): - -```python -from jaiminho.send import save_to_outbox - -@save_to_outbox -def any_external_call(**kwargs): - # do something - return -``` - # How Jaiminho works @@ -121,7 +77,7 @@ The Event Relaying command will query the database for all events that were not To ensure all failed events are re-sent by Jaiminho, you have two options with the Event Relaying command: - Schedule it to be regularly executed (with a cronjob, for example) -- Run it in a loop using the `--run_in_loop` and `--loop_interval` flags +- Run it in a loop using the `run_in_loop` and `loop_interval` flags ### Event Cleaning @@ -134,6 +90,58 @@ Jaiminho emits two Django signals, which can be used, for example, for collectin - `event_publish` : emitted when an event is successfully sent - `event_failed_to_published` : emitted when an event failed to be sent +# Using Jaiminho in your project + +To add Jaiminho to your project, you have to: + +1) Install it: + +```console +python -m pip install jaiminho +``` + +2) Add it to the Django project’s `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + "django.contrib.auth", + "django.contrib.contenttypes", + ... + ... + ... + "jaiminho" +] +``` + +3) Configure the options in the project’s Django `settings.py`: + +```python +JAIMINHO_CONFIG = { + "PERSIST_ALL_EVENTS": False, + "DELETE_AFTER_SEND": True, + "PUBLISH_STRATEGY: "keep-order" + } +``` + +4) Apply Jaiminhos migrations in order to create the event database table: + +```console +python manage.py migrate +``` + + +5) Add the `@save_to_outbox` decorator to any method responsible for communicating with external systems (brokers, external APIs, etc): + +```python +from jaiminho.send import save_to_outbox + +@save_to_outbox +def any_external_call(**kwargs): + # do something + return +``` + + # Final remarks If you are interested in learning more, there is a detailed documentation on the [GitHub repository](https://github.com/loadsmart/jaiminho). Also, contributions are more than welcome! Feel free to contribute if you find any bugs or have any suggestions. From 53c948e67212dcde32062ffe31f2326bf220975a Mon Sep 17 00:00:00 2001 From: Rafael Zanetti Date: Wed, 9 Nov 2022 15:59:38 -0300 Subject: [PATCH 4/9] pr suggestions --- content/posts/2022-09-14-introducing-jaiminho/index.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/content/posts/2022-09-14-introducing-jaiminho/index.md b/content/posts/2022-09-14-introducing-jaiminho/index.md index 9f22e7a..da384a4 100644 --- a/content/posts/2022-09-14-introducing-jaiminho/index.md +++ b/content/posts/2022-09-14-introducing-jaiminho/index.md @@ -123,7 +123,7 @@ JAIMINHO_CONFIG = { } ``` -4) Apply Jaiminhos migrations in order to create the event database table: +4) Apply Jaiminho’s migrations in order to create the event database table: ```console python manage.py migrate @@ -141,6 +141,11 @@ def any_external_call(**kwargs): return ``` +6) Now, to complete the flow, don’t forget to configure the Event Relayer to run according to your needs. For example, a simple way to set it to run every 15 seconds: + +```console +python3 manage.py events_relay loop_interval 15 +``` # Final remarks From adcd828b3a30707358576862b9f30cd0c53630a0 Mon Sep 17 00:00:00 2001 From: Rafael Zanetti Date: Thu, 10 Nov 2022 13:56:34 -0300 Subject: [PATCH 5/9] adding outbox image --- .../2022-09-14-introducing-jaiminho/index.md | 3 +++ .../2022-09-14-introducing-jaiminho/outbox.png | Bin 0 -> 38036 bytes 2 files changed, 3 insertions(+) create mode 100644 content/posts/2022-09-14-introducing-jaiminho/outbox.png diff --git a/content/posts/2022-09-14-introducing-jaiminho/index.md b/content/posts/2022-09-14-introducing-jaiminho/index.md index da384a4..d7749dc 100644 --- a/content/posts/2022-09-14-introducing-jaiminho/index.md +++ b/content/posts/2022-09-14-introducing-jaiminho/index.md @@ -16,6 +16,9 @@ There are well-known methods to deal with such issues, and we chose to apply the # The Transactional outbox pattern +![outbox](./outbox.png) + + For simplicity purposes, let’s assume the common case of an application that has to save data to a database and notify it to an event stream. The idea behind the transactional outbox pattern is combining both writes into a single atomic transaction, which guarantees that if one of them fails, the entire transaction fails, avoiding inconsistent scenarios; in this case, it means that if a record is persisted into the database, it is guaranteed to be notified to the stream. The pattern achieves this goal by introducing two concepts: - Outbox table diff --git a/content/posts/2022-09-14-introducing-jaiminho/outbox.png b/content/posts/2022-09-14-introducing-jaiminho/outbox.png new file mode 100644 index 0000000000000000000000000000000000000000..09cf0bb00c51e3425792d4dc37f5662292400738 GIT binary patch literal 38036 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 literal 0 HcmV?d00001 From e6129fd2a71c6d1d140101eeff849c7fcb39bb9c Mon Sep 17 00:00:00 2001 From: Rafael Zanetti Date: Thu, 10 Nov 2022 14:04:54 -0300 Subject: [PATCH 6/9] updating outbox image --- .../2022-09-14-introducing-jaiminho/index.md | 6 +++--- .../outbox.png | Bin 38036 -> 38509 bytes 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/posts/2022-09-14-introducing-jaiminho/index.md b/content/posts/2022-09-14-introducing-jaiminho/index.md index d7749dc..3a599b0 100644 --- a/content/posts/2022-09-14-introducing-jaiminho/index.md +++ b/content/posts/2022-09-14-introducing-jaiminho/index.md @@ -25,10 +25,10 @@ For simplicity purposes, let’s assume the common case of an application that h When storing a record to the database, the corresponding event should be persisted into an outbox table, and both operations should be in the same transaction. With this strategy we can leverage the atomicity property of relational databases transactions to ensure either both or no inserts will be successful. -- Message relay +- Message relayer -The outbox table is guaranteed to have all events that should be notified, so we just have to ensure that they are really sent. This responsibility goes to the message relay, which will publish all events in the table to the stream and mark them as sent. -Note: Since the message relay has to send an event and then mark it as sent, that characterizes another dual write, because if the relay fails to update the status after sending the event, it will be sent again on the next execution. So, to ensure no duplicated events are consumed, the message consumers must implement idempotence on their side. +The outbox table is guaranteed to have all events that should be notified, so we just have to ensure that they are really sent. This responsibility goes to the message relayer, which will publish all events in the table to the stream and mark them as sent. +Note: Since the message relay has to send an event and then mark it as sent, that characterizes another dual write, because if the relayer fails to update the status after sending the event, it will be sent again on the next execution. So, to ensure no duplicated events are consumed, the message consumers must implement idempotence on their side. # How Jaiminho works diff --git a/content/posts/2022-09-14-introducing-jaiminho/outbox.png b/content/posts/2022-09-14-introducing-jaiminho/outbox.png index 09cf0bb00c51e3425792d4dc37f5662292400738..c0bab1e7f1c5304266930feea17cfa5d2b793a23 100644 GIT binary patch literal 38509 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 KvaULGI{q&Y&31tR literal 38036 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 From 93b90e658b615ff9964895f5ed6af59e88e0ff3d Mon Sep 17 00:00:00 2001 From: Rafael Zanetti Date: Thu, 10 Nov 2022 14:07:54 -0300 Subject: [PATCH 7/9] fixing events_relay command --- content/posts/2022-09-14-introducing-jaiminho/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/posts/2022-09-14-introducing-jaiminho/index.md b/content/posts/2022-09-14-introducing-jaiminho/index.md index 3a599b0..6904671 100644 --- a/content/posts/2022-09-14-introducing-jaiminho/index.md +++ b/content/posts/2022-09-14-introducing-jaiminho/index.md @@ -147,7 +147,7 @@ def any_external_call(**kwargs): 6) Now, to complete the flow, don’t forget to configure the Event Relayer to run according to your needs. For example, a simple way to set it to run every 15 seconds: ```console -python3 manage.py events_relay loop_interval 15 +python manage.py events_relay loop_interval 15 ``` # Final remarks From 4426b80e79bfc35b94ae905754d835880a776c2c Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Rodrigues Pinto Tomas Date: Tue, 28 Feb 2023 16:49:11 -0300 Subject: [PATCH 8/9] chore: Wording --- content/posts/2022-09-14-introducing-jaiminho/index.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/posts/2022-09-14-introducing-jaiminho/index.md b/content/posts/2022-09-14-introducing-jaiminho/index.md index 6904671..96bd9ca 100644 --- a/content/posts/2022-09-14-introducing-jaiminho/index.md +++ b/content/posts/2022-09-14-introducing-jaiminho/index.md @@ -9,7 +9,7 @@ date: 2022-11-25 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. +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 write 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. @@ -47,9 +47,9 @@ Since the message and kwargs are serialized into bytes, any type of message is s With Jaiminho, you can choose between the following two publish strategies, using the `PUBLISH_STRATEGY` configuration: -### Keep Order -This strategy is similar to the transactional outbox [described by Chris Richardson](https://microservices.io/patterns/data/transactional-outbox.html). The decorated function intercepts the function call and saves it on local DB to be executed later. A separate event relayer will keep polling local DB and executing those functions in the same order it was stored. -Be careful with this approach, **if any execution fails, the relayer will get stuck**. Otherwise, it would not possible to guarantee delivery order. +### Keep Order +This strategy is similar to the transactional outbox [described by Chris Richardson](https://microservices.io/patterns/data/transactional-outbox.html). The decorated function intercepts the function call and saves it on local DB to be executed later. A separate event relayer will keep polling local DB and executing those functions in the same order it was stored. +Be careful with this approach, **if any execution fails, the relayer will get stuck**. Otherwise, it would not possible to guarantee delivery order. ### Publish on commit @@ -150,6 +150,6 @@ def any_external_call(**kwargs): python manage.py events_relay loop_interval 15 ``` -# Final remarks +# Final remarks If you are interested in learning more, there is a detailed documentation on the [GitHub repository](https://github.com/loadsmart/jaiminho). Also, contributions are more than welcome! Feel free to contribute if you find any bugs or have any suggestions. From d8fa7ecd19df1eaac2ead51bd566322a8e1e5e56 Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Rodrigues Pinto Tomas Date: Thu, 2 Mar 2023 09:11:30 -0300 Subject: [PATCH 9/9] minor improvements --- .../2022-09-14-introducing-jaiminho/index.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/content/posts/2022-09-14-introducing-jaiminho/index.md b/content/posts/2022-09-14-introducing-jaiminho/index.md index 96bd9ca..340ee4a 100644 --- a/content/posts/2022-09-14-introducing-jaiminho/index.md +++ b/content/posts/2022-09-14-introducing-jaiminho/index.md @@ -9,9 +9,9 @@ date: 2022-11-25 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 write 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. +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 write data in 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 that may be consumed by different services. The inherent issue with this scenario is that if one of these 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 will cause the consumer to receive 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. +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 in the [Django community](https://djangopackages.org/search/?q=outbox), we decided to implement an open-source library called [Jaiminho](https://github.com/loadsmart/django-jaiminho)(available through [Pypi](https://pypi.org/project/django-jaiminho/)), a broker-agnostic implementation of the outbox pattern. # The Transactional outbox pattern @@ -23,7 +23,7 @@ For simplicity purposes, let’s assume the common case of an application that h - Outbox table -When storing a record to the database, the corresponding event should be persisted into an outbox table, and both operations should be in the same transaction. With this strategy we can leverage the atomicity property of relational databases transactions to ensure either both or no inserts will be successful. +When storing a record in the database, the corresponding event should be persisted into an outbox table, and both operations should be in the same transaction. With this strategy, we can leverage the atomicity property of relational database transactions to ensure either both or no inserts will be successful. - Message relayer @@ -39,16 +39,16 @@ With the default configuration, when you add the `@save_to_outbox` decorator to - The method that was used for sending that message - The extra kwargs used to call the method -This data will allow for the message to be sent again using the original method, message and kwargs. Also, at the end of the decorated method a Django signal will be sent to indicate the event success or failure. +This data will allow for the message to be sent again using the original method, message and kwargs. Also, at the end of the decorated method a Django signal will be sent to indicate the event's success or failure. -Since the message and kwargs are serialized into bytes, any type of message is supported. For example, in Loadsmart we work with JSON and Protobuf messages, and both are using Jaiminho with no need of special configurations. +Since the message and kwargs are serialized into bytes, any type of message is supported. For example, in Loadsmart we work with JSON and Protobuf messages, and both are using Jaiminho with no need for special configurations. ## Publish strategies With Jaiminho, you can choose between the following two publish strategies, using the `PUBLISH_STRATEGY` configuration: ### Keep Order -This strategy is similar to the transactional outbox [described by Chris Richardson](https://microservices.io/patterns/data/transactional-outbox.html). The decorated function intercepts the function call and saves it on local DB to be executed later. A separate event relayer will keep polling local DB and executing those functions in the same order it was stored. +This strategy is similar to the transactional outbox [described by Chris Richardson](https://microservices.io/patterns/data/transactional-outbox.html). The decorated function intercepts the function call and saves it on the local DB to be executed later. A separate event relayer will keep polling local DB and executing those functions in the same order it was stored. Be careful with this approach, **if any execution fails, the relayer will get stuck**. Otherwise, it would not possible to guarantee delivery order. ### Publish on commit @@ -61,7 +61,7 @@ Besides the publish strategies, there are two other options that can be configur ### Persist all events -While the default behavior of Jaiminho makes losing an event less likely, it still has a point of failure: if the notifying method fails and Jaiminho receives an error trying to store the database entry, the event will be lost. In order to avoid this possibility, the `PERSIST_ALL_EVENTS` configuration can be set to True, which will save the database entry *before* trying to notify the event. In this case, the notifying method will be called when the database transaction is committed, which will ensure that the event is persisted. This is not applicable when the publish strategy is **Keep order**, because all the messages must be stored to achieve this strategy. +While the default behavior of Jaiminho makes losing an event less likely, it still has a point of failure: if the notifying method fails and Jaiminho receives an error trying to store the database entry, the event will be lost. In order to avoid this possibility, the `PERSIST_ALL_EVENTS` configuration can be set to True, which will save the database entry *before* trying to notify the event. In this case, the notifying method will be called when the database transaction is committed, which will ensure that the event is persisted. This is not applicable when the publishing strategy is **Keep order**, because all the messages must be stored to achieve this strategy. ### Delete after send @@ -75,7 +75,7 @@ Jaiminho comes with two Django Commands that can be useful: ### Event Relaying -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. +The Event Relaying command will query the database for all events that were not sent in a given timebox and will try to resend them using the original method, message and kwargs. Note that if the event relay runs after a deployment that changed or removed the original method, it will not be able to resend the failed events and they will have to be dealt with manually. Also, the `DELETE_AFTER_SEND` configuration also applies to this command. To ensure all failed events are re-sent by Jaiminho, you have two options with the Event Relaying command: @@ -100,7 +100,7 @@ To add Jaiminho to your project, you have to: 1) Install it: ```console -python -m pip install jaiminho +python -m pip install django-jaiminho ``` 2) Add it to the Django project’s `INSTALLED_APPS`: @@ -152,4 +152,4 @@ python manage.py events_relay loop_interval 15 # Final remarks -If you are interested in learning more, there is a detailed documentation on the [GitHub repository](https://github.com/loadsmart/jaiminho). Also, contributions are more than welcome! Feel free to contribute if you find any bugs or have any suggestions. +If you are interested in learning more, there is a detailed documentation on the [GitHub repository](https://github.com/loadsmart/django-jaiminho). Also, contributions are more than welcome! Feel free to contribute if you find any bugs or have any suggestions.