Skip to content

Commit 11603d6

Browse files
authored
Merge pull request #31 from cloudblue/lite-18056-retry-docs
LITE-18056 Added CQRS retry docs
2 parents e214de6 + 37e9886 commit 11603d6

File tree

5 files changed

+153
-1
lines changed

5 files changed

+153
-1
lines changed

docs/_static/css/custom.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
Copyright © 2021 Ingram Micro Inc. All rights reserved.
3+
*/
4+
.wy-table-responsive table {
5+
width: 100%;
6+
}
7+
8+
.wy-table-responsive table td {
9+
white-space: normal;
10+
}
11+
12+
.wy-nav-content{
13+
max-width: 1000px;
14+
}

docs/_static/img/lifecycle.png

25.9 KB
Loading

docs/conf.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Copyright © 2021 Ingram Micro Inc. All rights reserved.
2+
13
import os
24
import sys
35
from datetime import datetime
@@ -15,7 +17,7 @@
1517
# -- Project information -----------------------------------------------------
1618

1719
project = 'django-cqrs'
18-
copyright = '{}, CloudBlue Inc.'.format(datetime.now().year)
20+
copyright = '{}, Ingram Micro Inc.'.format(datetime.now().year)
1921
author = 'CloudBlue'
2022

2123
# The full version, including alpha/beta/rc tags
@@ -56,3 +58,9 @@
5658
# relative to this directory. They are copied after the builtin static files,
5759
# so a file named "default.css" will overwrite the builtin "default.css".
5860
html_static_path = ['_static']
61+
62+
# These paths are either relative to html_static_path
63+
# or fully qualified paths (eg. https://...)
64+
html_css_files = [
65+
'css/custom.css',
66+
]

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ and that's okay for non-critical business transactions.
3535
custom_serialization
3636
track_fields_changes
3737
transports
38+
lifecycle
3839
utilities
3940
reference
4041

docs/lifecycle.rst

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
.. _lifecycle:
2+
3+
Message lifecycle
4+
=================
5+
.. warning::
6+
7+
Expiration, retrying and dead letter supports only ``RabbitMQTransport`` (on by default).
8+
9+
`django-cqrs` since version 1.11 provides mechanism for reliable message delivery.
10+
11+
.. image:: _static/img/lifecycle.png
12+
:scale: 50 %
13+
:alt: Message lifecycle
14+
15+
Expiration
16+
----------
17+
+------------------+------------+--------------------------------------------------------------------------------------------------+
18+
| Name | Default | Description |
19+
+==================+============+==================================================================================================+
20+
| CQRS_MESSAGE_TTL | 86400 | Limits message lifetime in **seconds**, after that period it will be moved to dead letter queue. |
21+
+------------------+------------+--------------------------------------------------------------------------------------------------+
22+
23+
.. code-block:: python
24+
25+
# settings.py
26+
27+
CQRS = {
28+
...
29+
'master': {
30+
'CQRS_MESSAGE_TTL': 86400, # 1 day
31+
},
32+
}
33+
34+
Fail
35+
----
36+
Message is failed when consume raises any exception or returns negative boolean value (False, None).
37+
38+
.. code-block:: python
39+
40+
# models.py
41+
42+
class Example(ReplicaMixin, models.Model):
43+
CQRS_ID = 'example'
44+
...
45+
46+
@classmethod
47+
def cqrs_create(cls, sync, mapped_data, previous_data=None):
48+
raise Exception("Some issue during create") # exception could be caught at should_retry_cqrs method
49+
50+
@classmethod
51+
def cqrs_update(self, sync, mapped_data, previous_data=None):
52+
return None # returning negative boolean triggers retrying
53+
54+
Retrying
55+
--------
56+
+----------------------+----------+----------------------------------------------------------------------------+
57+
| Name | Default | Description |
58+
+======================+==========+============================================================================+
59+
| CQRS_MAX_RETRIES | 30 | Maximum number of retry attempts. Infinite if None, 0 for retry disabling. |
60+
+----------------------+----------+----------------------------------------------------------------------------+
61+
| CQRS_RETRY_DELAY | 2 | Constant delay in **seconds** between message fail and requeue. |
62+
+----------------------+----------+----------------------------------------------------------------------------+
63+
| delay_queue_max_size | None | Maximum number of delayed messages per worker. Infinite if None. |
64+
+----------------------+----------+----------------------------------------------------------------------------+
65+
66+
.. code-block:: python
67+
68+
# settings.py
69+
70+
CQRS = {
71+
...
72+
'replica': {
73+
'CQRS_MAX_RETRIES': 30, # attempts
74+
'CQRS_RETRY_DELAY': 2, # seconds
75+
'delay_queue_max_size': None, # infinite
76+
},
77+
}
78+
79+
Customization
80+
^^^^^^^^^^^^^
81+
The :class:`dj_cqrs.mixins.ReplicaMixin` allows to set retrying behaviour manually.
82+
83+
.. code-block:: python
84+
85+
# models.py
86+
87+
class Example(ReplicaMixin, models.Model):
88+
CQRS_ID = 'example'
89+
...
90+
91+
@classmethod
92+
def get_cqrs_retry_delay(cls, current_retry=0):
93+
# Linear delay growth
94+
return (current_retry + 1) * 60
95+
96+
@classmethod
97+
def should_retry_cqrs(cls, current_retry, exception=None):
98+
# Retry 10 times or until we have troubles with database
99+
return (
100+
current_retry < 10
101+
or isinstance(exception, django.db.OperationalError)
102+
)
103+
104+
Dead letter
105+
-----------
106+
Expired or failed messages which should not be retried moved to dead letter queue.
107+
108+
+-------------------+------------------------+----------------------------------------------------+
109+
| Name | Default | Description |
110+
+===================+========================+====================================================+
111+
| dead_letter_queue | dead_letter + queue | Queue name for dead letter messages. |
112+
+-------------------+------------------------+----------------------------------------------------+
113+
| dead_message_ttl | 864000 | Expiration **seconds**. Infinite if None. |
114+
+-------------------+------------------------+----------------------------------------------------+
115+
116+
.. code-block:: python
117+
118+
# settings.py
119+
120+
CQRS = {
121+
...
122+
'queue': 'example',
123+
'replica': {
124+
...
125+
'dead_letter_queue': 'dead_letter_example', # generates from CQRS.queue
126+
'dead_message_ttl': 864000, # 10 days
127+
},
128+
}
129+

0 commit comments

Comments
 (0)