Skip to content

Commit 46dbff8

Browse files
dgafkagitbook-bot
authored andcommitted
GITBOOK-882: No subject
1 parent 71c81b7 commit 46dbff8

File tree

18 files changed

+223
-73
lines changed

18 files changed

+223
-73
lines changed

Diff for: SUMMARY.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@
7575
* [Recovering, Tracing and Monitoring](modelling/recovering-tracing-and-monitoring/README.md)
7676
* [Resiliency](modelling/recovering-tracing-and-monitoring/resiliency/README.md)
7777
* [Retries](modelling/recovering-tracing-and-monitoring/resiliency/retries.md)
78-
* [Error Channel and Dead Letter](modelling/recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter.md)
78+
* [Error Channel and Dead Letter](modelling/recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter/README.md)
79+
* [Dbal Dead Letter](modelling/recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter/dbal-dead-letter.md)
7980
* [Idempotent Consumer (Deduplication)](modelling/recovering-tracing-and-monitoring/resiliency/idempotent-consumer-deduplication.md)
8081
* [Resilient Sending](modelling/recovering-tracing-and-monitoring/resiliency/resilient-sending.md)
8182
* [Outbox Pattern](modelling/recovering-tracing-and-monitoring/resiliency/outbox-pattern.md)

Diff for: messaging/messaging-concepts/message-channel.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: Message Channel PHP
66

77
![](../../.gitbook/assets/message-channel-connection.svg)
88

9-
_`Message channel`_abstracts communication between components. It does allow for sending and receiving messages.\
9+
_`Message channel`_abstracts communication between components. It does allow for sending and receiving messages.\
1010
A message channel may follow either point-to-point or publish-subscribe semantics. \
1111
With a point-to-point channel, only one consumer can receive each message sent to the channel. \
1212
Publish-subscribe channels, broadcast each message to all subscribers on the channel. 

Diff for: messaging/multi-tenancy-support/different-scenarios/multi-tenant-aware-dead-letter.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Multi-Tenant aware Dead Letter
22

3-
When executing [Dead Letter Console Command](../../../modelling/recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter.md#dead-letter-console-commands) we will lack of Context of the Tenant we are using.\
3+
When executing [Dead Letter Console Command](../../../modelling/recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter/#dead-letter-console-commands) we will lack of Context of the Tenant we are using.\
44
To handle that we may use Ecotone's [support for passing Message Headers](../../console-commands.md#passing-message-headers) together with Console Command.
55

66
### Example

Diff for: messaging/workflows/handling-failures.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ This kind of explicit way of solving problems allows us to switch the code from
115115

116116
## Recoverable Synchronous Errors
117117

118-
One of the problems that we need to accept is that [Network is not reliable](https://en.wikipedia.org/wiki/Fallacies\_of\_distributed\_computing). This means that that when we will want to store something in our Database, send an Message to the Message Broker or call External Service, network may simply fail and there are various reasons why it may happen.
118+
One of the problems that we need to accept is that [Network is not reliable](https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing). This means that that when we will want to store something in our Database, send an Message to the Message Broker or call External Service, network may simply fail and there are various reasons why it may happen.
119119

120120
In our case, if we would want to store our Order synchronously, or send an Message to the Broker, it may happen that we will face an error. This of course means that Customer will not completely his Order, which is far from ideal. 
121121

@@ -140,7 +140,7 @@ In those situations we still want to Application to seal-heal, so we don't need
140140
In case External Service is down for longer period of time, we may actually not be able to self-heal. \
141141
In case of coding errors (bugs) we may also end up in situation where not matter how many retries we would do, we still won't recover.
142142

143-
For this situation, Ecotone provides [Dead Letter Storage](../../modelling/recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter.md), which allows us to store the the Message and replay after the problem is fixed. 
143+
For this situation, Ecotone provides [Dead Letter Storage](../../modelling/recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter/), which allows us to store the the Message and replay after the problem is fixed. 
144144

145145
<figure><img src="../../.gitbook/assets/dead-letter (1).png" alt=""><figcaption><p>Store in Dead Letter when urecoverable and replay when needed</p></figcaption></figure>
146146

@@ -153,7 +153,7 @@ And if unrecoverable error happens, we get ability to easily replay the Message
153153

154154
If we already have some solution to handle Asynchronous Errors in our Application, we can take over the process using Error Channel. Error Chanel is a Message Channel where all unhandled Asynchronous Errors go. \
155155
\
156-
You can read more about in [related documentation](../../modelling/recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter.md#error-channel).
156+
You can read more about in [related documentation](../../modelling/recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter/#error-channel).
157157

158158
## Customizing Error Handling on Message Handler Level
159159

Diff for: modelling/event-sourcing/event-sourcing-introduction/event-versioning.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ This feature is available as part of **Ecotone Enterprise.**
4747

4848
Depending on the version we may actually want to restore our Aggregate a bit differently. \
4949
This is especially useful when we've changed the way Events are structured and introduced new version of the Event. \
50-
For this we can use **revision header** to access the version on which given Event was stored**.**
50+
For this we can use **revision header** to access the version on which given Event was store&#x64;**.**
5151

5252
```php
5353
#[EventSourcingAggregate]
@@ -79,5 +79,5 @@ class Product
7979

8080
{% hint style="success" %}
8181
We may inject any type of Header that was stored together with the Event. \
82-
This means inbuilt headers like **timestamp**, **id**, **correlationId are avaiable** out of the box**.**
82+
This means inbuilt headers like **timestamp**, **id**, **correlationId are avaiable** out of the bo&#x78;**.**
8383
{% endhint %}

Diff for: modelling/event-sourcing/setting-up-projections/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ We need to touch on one more important topic. Where do we actually get the data
181181
## The source of data for Projection
182182

183183
Events that trigger Projections are not actually a source of the data for them.\
184-
This is because if we would lose Event Message along the way due some failure (For example we don't use [Outbox](../../recovering-tracing-and-monitoring/resiliency/outbox-pattern.md)) or it would and in [Dead Letter](../../recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter.md) then we would basically skip over an Event.
184+
This is because if we would lose Event Message along the way due some failure (For example we don't use [Outbox](../../recovering-tracing-and-monitoring/resiliency/outbox-pattern.md)) or it would and in [Dead Letter](../../recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter/) then we would basically skip over an Event.
185185

186186
Let's take as an example Asynchronous Projection, where we want to store Ticket with new "**alert-warning**" type. However let's suppose we've created column with limited size for type - which is up to 10 characters. Therefore our Projection will fail on storing that, because the type is 13 characters long:
187187

Diff for: modelling/event-sourcing/setting-up-projections/emitting-events.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ In order to emit the events, we are using `EventStreamEmitter`.\
3939
Whenever we `emit` given events, they are stored in Projection's stream.
4040

4141
{% hint style="info" %}
42-
Events are stored in stream called project_{projectionName}._ In above case it will be _project\_wallet\_balance._
42+
Events are stored in stream called projec&#x74;_{projectionName}._ In above case it will be _project\_wallet\_balance._
4343
{% endhint %}
4444

4545
After that you may subscribe to given events, just like to any other events.

Diff for: modelling/extending-messaging-middlewares/message-headers.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Using already propagated Headers, we may build our own tracing solution on top o
110110

111111
### Id
112112

113-
Each Message receives it's own unique Id, which is Uuid generated value. This is used by Ecotone to provide capabilities like [Message Deduplication](../recovering-tracing-and-monitoring/resiliency/idempotent-consumer-deduplication.md), [Tracing](../../modules/opentelemetry-tracing-and-metrics/) and Message identification for [Retries and Dead Letter](../recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter.md).
113+
Each Message receives it's own unique Id, which is Uuid generated value. This is used by Ecotone to provide capabilities like [Message Deduplication](../recovering-tracing-and-monitoring/resiliency/idempotent-consumer-deduplication.md), [Tracing](../../modules/opentelemetry-tracing-and-metrics/) and Message identification for [Retries and Dead Letter](../recovering-tracing-and-monitoring/resiliency/error-channel-and-dead-letter/).
114114

115115
### Parent Id
116116

Diff for: modelling/recovering-tracing-and-monitoring/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Ecotone provides solutions to handle failures within the system that helps in:
55

66
* Self-healing the application ([Instant and Delayed Message Handling Retries](resiliency/retries.md), [Locking](resiliency/concurrency-handling.md), [Isolation of failures](message-handling-isolation.md))
77
* Ensuring Data Consistency ([Resilient Message Sending](resiliency/resilient-sending.md), [Outbox pattern](resiliency/outbox-pattern.md), [Message Deduplication](resiliency/idempotent-consumer-deduplication.md))
8-
* Recovering ([Dead Letter](resiliency/error-channel-and-dead-letter.md), [Tracing](../../modules/opentelemetry-tracing-and-metrics/), [Monitoring](ecotone-pulse-service-dashboard.md))
8+
* Recovering ([Dead Letter](resiliency/error-channel-and-dead-letter/), [Tracing](../../modules/opentelemetry-tracing-and-metrics/), [Monitoring](ecotone-pulse-service-dashboard.md))
99

1010
{% hint style="success" %}
1111
To find out more about different use-cases, read related section about [Handling Failures in Workflows](../../messaging/workflows/handling-failures.md).

Diff for: modelling/recovering-tracing-and-monitoring/ecotone-pulse-service-dashboard.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Ecotone Pulse provide way to control error messages for all your services from o
1212

1313
## Installation
1414

15-
Enable [Dead Letter](resiliency/error-channel-and-dead-letter.md) in your service and [Distributed Consumer](../../modules/amqp-support-rabbitmq.md#distributed-consumer) with [AMQP Module](../../modules/amqp-support-rabbitmq.md#installation).
15+
Enable [Dead Letter](resiliency/error-channel-and-dead-letter/) in your service and [Distributed Consumer](../../modules/amqp-support-rabbitmq.md#distributed-consumer) with [AMQP Module](../../modules/amqp-support-rabbitmq.md#installation).
1616

1717
After this you may run docker image with Ecotone Pulse passing the configuration to your services and RabbitMQ connection.
1818

Diff for: modelling/recovering-tracing-and-monitoring/resiliency/concurrency-handling.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,4 @@ To handle concurrency exceptions and ensure the system can self-heal, Ecotone of
4141

4242
_In synchronous scenarios_, like Command Handler being called via HTTP, [instant retries](retries.md#instant-retries) can be used to recover. If a concurrency exception occurs, the Command Message will be retried immediately, minimizing any impact on the end user. This immediate retry ensures that the Message Handler can self-heal and continue processing without affecting the user experience.\
4343
\
44-
_In asynchronous scenarios_, you can use still use instant retries, yet you may also provide [delayed retries](retries.md#delayed-retries). This means that when concurrency exception will occur, the Message will be retried after a certain delay. This as a result free the system resources from continues retries and allows for recovering after given period of delay.
44+
&#xNAN;_&#x49;n asynchronous scenarios_, you can use still use instant retries, yet you may also provide [delayed retries](retries.md#delayed-retries). This means that when concurrency exception will occur, the Message will be retried after a certain delay. This as a result free the system resources from continues retries and allows for recovering after given period of delay.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Error Channel and Dead Letter
2+
3+
## Error Channel
4+
5+
`Ecotone` comes with solution called Error Channel. \
6+
Error Channel is a place where unrecoverable Errors can go, this way we can preserve Error Messages even if we can't handle anyhow. \
7+
Error Channel may log those Messages, store them in database, push them to some Asynchronous Channel. The what is to be done is flexibile and can be adjusted to Application needs.
8+
9+
## Configuration
10+
11+
Error Channel can be configured per Message Consumer, or globally as default Error Channel for all Message Consumers:
12+
13+
* [Set up default error channel for all consumers](../../../../messaging/service-application-configuration.md#ecotone-core-configuration)
14+
15+
&#x20; \- [Symfony](../../../../modules/symfony/symfony-ddd-cqrs-event-sourcing.md#defaulterrorchannel)
16+
17+
&#x20; \- [Laravel](../../../../modules/laravel/laravel-ddd-cqrs-event-sourcing.md#defaulterrorchannel)
18+
19+
&#x20; \- [Lite](../../../../modules/ecotone-lite/#withdefaulterrorchannel)
20+
21+
{% tabs %}
22+
{% tab title="Symfony" %}
23+
**config/packages/ecotone.yaml**
24+
25+
```yaml
26+
ecotone:
27+
defaultErrorChannel: "errorChannel"
28+
```
29+
{% endtab %}
30+
31+
{% tab title="Laravel" %}
32+
**config/ecotone.php**
33+
34+
```php
35+
return [
36+
'defaultErrorChannel' => 'errorChannel',
37+
];
38+
```
39+
{% endtab %}
40+
41+
{% tab title="Lite" %}
42+
```php
43+
$ecotone = EcotoneLite::bootstrap(
44+
configuration: ServiceConfiguration::createWithDefaults()
45+
->withDefaultErrorChannel('errorChannel')
46+
);
47+
```
48+
{% endtab %}
49+
{% endtabs %}
50+
51+
* [Set up for specific consumer](../../../asynchronous-handling/#static-configuration)
52+
53+
```php
54+
class Configuration
55+
{
56+
#[ServiceContext]
57+
public function configuration() : array
58+
{
59+
return [
60+
// For Message Consumer orders, configure error channel
61+
PollingMetadata::create("orders")
62+
->setErrorChannelName("errorChannel")
63+
];
64+
}
65+
}
66+
```
67+
68+
{% hint style="info" %}
69+
Setting up Error Channel means that [Message Consumer](../../../../messaging/contributing-to-ecotone/demo-integration-with-sqs/message-consumer-and-publisher.md#message-consumer) will send Error Message to error channel and then continue handling next messages.\
70+
\
71+
After sending Error Message to Error Channel, message is considered handled as long as Error Handler does not throw exception.
72+
{% endhint %}
73+
74+
## Manual Handling
75+
76+
To handle incoming Error Messages, we can bind to our defined Error Channel using [ServiceActivator](../../../../messaging/messaging-concepts/):
77+
78+
```php
79+
#[ServiceActivator("errorChannel")]
80+
public function handle(ErrorMessage $errorMessage): void
81+
{
82+
// do something with ErrorMessage
83+
}
84+
```
85+
86+
{% hint style="info" %}
87+
Service Activator are endpoints like Command Handlers, however they are not exposed using Command/Event/Query Buses. \
88+
You may use them for internal handling.
89+
{% endhint %}
90+
91+
## Delayed Retries
92+
93+
We can also use inbuilt retry mechanism, that will be resend Error Message to it's original Message Channel with delay. If our Default Error Channel is configured for name **"errorChannel"**, then we can connect it like bellow:
94+
95+
```php
96+
#[ServiceContext]
97+
public function errorConfiguration()
98+
{
99+
return ErrorHandlerConfiguration::create(
100+
"errorChannel",
101+
RetryTemplateBuilder::exponentialBackoff(1000, 10)
102+
->maxRetryAttempts(3)
103+
);
104+
}
105+
```
106+
107+
## Discarding all Error Messages
108+
109+
If for some cases we want to discard Error Messages, we can set up error channel to default inbuilt one called **"nullChannel"**. \
110+
That may be used in combination of retries, if after given attempt Message is still not handled, then discard:
111+
112+
```php
113+
#[ServiceContext]
114+
public function errorConfiguration()
115+
{
116+
return ErrorHandlerConfiguration::createWithDeadLetterChannel(
117+
"errorChannel",
118+
RetryTemplateBuilder::exponentialBackoff(1000, 10)
119+
->maxRetryAttempts(3),
120+
// if retry strategy will not recover, then discard
121+
"nullChannel"
122+
);
123+
}
124+
```
125+
126+
## Dbal Dead Letter
127+
128+
Ecotone comes with full support for managing full life cycle of a error message. Read more in next [section](dbal-dead-letter.md).

0 commit comments

Comments
 (0)