aws-elasticache-integration-client 0.0.2rc1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aws_elasticache_integration_client-0.0.2rc1/LICENSE +201 -0
- aws_elasticache_integration_client-0.0.2rc1/MANIFEST.in +2 -0
- aws_elasticache_integration_client-0.0.2rc1/PKG-INFO +264 -0
- aws_elasticache_integration_client-0.0.2rc1/README.md +239 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/__init__.py +48 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/auth.py +94 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/client.py +259 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/config_policy.py +27 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/connection.py +869 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/connection_manager.py +413 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/exceptions.py +101 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/hooks.py +254 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/idempotency.py +24 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/idempotent-operations.json +30 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/models.py +46 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/predicates.py +182 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/protocol.py +220 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/reconnect_policy.py +78 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/refresh.py +95 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/resp.py +237 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client/session.py +390 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client.egg-info/PKG-INFO +264 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client.egg-info/SOURCES.txt +26 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client.egg-info/dependency_links.txt +1 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client.egg-info/requires.txt +16 -0
- aws_elasticache_integration_client-0.0.2rc1/aws_elasticache_integration_client.egg-info/top_level.txt +1 -0
- aws_elasticache_integration_client-0.0.2rc1/pyproject.toml +80 -0
- aws_elasticache_integration_client-0.0.2rc1/setup.cfg +4 -0
- aws_elasticache_integration_client-0.0.2rc1/setup.py +34 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aws-elasticache-integration-client
|
|
3
|
+
Version: 0.0.2rc1
|
|
4
|
+
Summary: ElastiCache Integrations for AWS SDK for Python (Boto3) DynamoDB clients.
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Project-URL: Repository, https://github.com/awslabs/aws-elasticache-integration-client
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: boto3<2,>=1.43
|
|
11
|
+
Requires-Dist: botocore<2,>=1.43
|
|
12
|
+
Requires-Dist: cel-python>=0.1
|
|
13
|
+
Requires-Dist: developer-toolkit-elasticache<2,>=1.1
|
|
14
|
+
Provides-Extra: test
|
|
15
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
16
|
+
Requires-Dist: pytest-cov>=4; extra == "test"
|
|
17
|
+
Requires-Dist: cryptography>=42; extra == "test"
|
|
18
|
+
Requires-Dist: packaging>=24; extra == "test"
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: ruff==0.17.3; extra == "dev"
|
|
21
|
+
Requires-Dist: mypy==2.4.1; extra == "dev"
|
|
22
|
+
Requires-Dist: build==1.6.1; extra == "dev"
|
|
23
|
+
Requires-Dist: twine==7.0.0; extra == "dev"
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# ElastiCacheIntegrations (Python client)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## Install & test
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
cd python
|
|
33
|
+
pip install -e '.[test]' # runtime deps plus pytest and TLS test fixtures
|
|
34
|
+
python -m pytest # see tests/README.md for details
|
|
35
|
+
pip install -e '.[dev]' # pinned ruff, mypy, build, twine
|
|
36
|
+
ruff format --check . && ruff check . && mypy
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Runtime requires Python ≥ 3.10. See [`tests/README.md`](tests/README.md) for the test layout and
|
|
40
|
+
how to run the unit vs. end-to-end tests.
|
|
41
|
+
|
|
42
|
+
## Releases
|
|
43
|
+
|
|
44
|
+
Python publication is driven by annotated Git tags. Stable releases use
|
|
45
|
+
`vMAJOR.MINOR.PATCH`; release candidates use `vMAJOR.MINOR.PATCH-rc.N`, which maps to the
|
|
46
|
+
PEP 440 version `MAJOR.MINOR.PATCHrcN`. A release tag applies to every language client: Node,
|
|
47
|
+
Python, and Java release together.
|
|
48
|
+
|
|
49
|
+
The tag is the release version source of truth. The `Python Release` workflow
|
|
50
|
+
converts it to PEP 440 form and stamps `pyproject.toml` only in its temporary
|
|
51
|
+
checkout, leaving the checked-in version at its local development baseline. It
|
|
52
|
+
runs the reusable Python CI workflow, builds one wheel and one source
|
|
53
|
+
distribution, and smoke tests the wheel on Python 3.10, 3.12, and 3.14 before
|
|
54
|
+
waiting for approval from the protected `release` environment and publishing
|
|
55
|
+
with PyPI trusted publishing and attestations. The workflow verifies the
|
|
56
|
+
published version and attaches the distributions plus `python-SHA256SUMS` to
|
|
57
|
+
the matching GitHub Release.
|
|
58
|
+
|
|
59
|
+
The PyPI distribution name is `aws-elasticache-integration-client`, and the import package is
|
|
60
|
+
`aws_elasticache_integration_client`. The PyPI project must
|
|
61
|
+
configure `.github/workflows/python-release.yml` as its trusted publisher for the `release`
|
|
62
|
+
environment. No PyPI token is used by the workflow. A manual workflow run performs the same test,
|
|
63
|
+
packaging, artifact validation, and wheel smoke stages for an optional version
|
|
64
|
+
without entering the release environment or publishing to PyPI.
|
|
65
|
+
|
|
66
|
+
## Current state
|
|
67
|
+
|
|
68
|
+
The library delivers the happy path: intercept → serialize → `aws.config` handshake →
|
|
69
|
+
`aws.request` → return the cached response over a real TLS RESP3 connection, with
|
|
70
|
+
session-level IAM auth. The transport runs on a **pure-Python RESP3 connector**
|
|
71
|
+
(`ElastiCacheIntegrationsConnector`) — no Glide or other native dependency.
|
|
72
|
+
Its per-request timeout defaults to 5000 ms and can be changed with the
|
|
73
|
+
`cache_request_timeout` field (see below).
|
|
74
|
+
|
|
75
|
+
Cache requests may complete out of order when the cache returns a request ID and later delivers
|
|
76
|
+
the result in a `aws.response` RESP3 push. Deferred requests do not block later FIFO replies. If a
|
|
77
|
+
deferred request times out, only that request is abandoned, and a late push for its ID is dropped.
|
|
78
|
+
A timeout while a request is still FIFO-correlated closes the connection to prevent reply
|
|
79
|
+
misrouting. A RESP3 push with an unrecognized kind is treated as protocol corruption and closes
|
|
80
|
+
the connection. One connection sends at most 100 requests awaiting replies at once. Additional
|
|
81
|
+
callers wait for a slot within their `cache_request_timeout` instead of failing at the concurrency
|
|
82
|
+
boundary. Queue admission uses at most 75% of that timeout, reserving 25% to send and receive a
|
|
83
|
+
reply. If that budget is exhausted, the request is not sent to the cache and continues to origin
|
|
84
|
+
regardless of operation idempotency.
|
|
85
|
+
|
|
86
|
+
## Installing into a client
|
|
87
|
+
|
|
88
|
+
`install()` takes a boto3 client the application already built, so the client keeps its own
|
|
89
|
+
profile, `botocore.config.Config`, endpoint and everything else, and its region and credentials
|
|
90
|
+
are the ones the cache is authenticated with.
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
import boto3
|
|
94
|
+
import aws_elasticache_integration_client
|
|
95
|
+
|
|
96
|
+
ddb = boto3.client("dynamodb", region_name="us-east-1")
|
|
97
|
+
|
|
98
|
+
aws_elasticache_integration_client.install(
|
|
99
|
+
client=ddb, endpoint="my-cache:6379", cache_name="my-cache"
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
ddb.get_item(TableName="my-table", Key={"id": {"S": "1"}}) # unchanged
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
| Argument | Default | Meaning |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| `client` | required | The boto3 client to route through the cache. |
|
|
108
|
+
| `endpoint` | required | Cache endpoint as `host:port`. |
|
|
109
|
+
| `cache_name` | required | The ElastiCache Serverless cache name. |
|
|
110
|
+
| `user_id` | `default.iam-user` | ElastiCache IAM user id. |
|
|
111
|
+
| `verify` | `True` | Verify the cache's TLS certificate. `False` is for self-signed test rigs only. |
|
|
112
|
+
| `ca_certs` | `None` | CA bundle for the cache's certificate, instead of the system trust store. |
|
|
113
|
+
| `client_configuration` | all defaults | See [Configuration](#configuration). |
|
|
114
|
+
|
|
115
|
+
Everything above describes the connection to the **cache**, which the boto3 client knows nothing
|
|
116
|
+
about. TLS to AWS, and everything else about reaching the service, stays the client's own
|
|
117
|
+
configuration.
|
|
118
|
+
|
|
119
|
+
Closing the client disconnects the cache first, then closes the client as usual. A client can
|
|
120
|
+
have the cache installed once; a second `install()` on the same client raises
|
|
121
|
+
`ElastiCacheIntegrationsConfigError`.
|
|
122
|
+
|
|
123
|
+
## Configuration
|
|
124
|
+
|
|
125
|
+
Optional ElastiCacheIntegrations settings go in one `aws_elasticache_integration_client.ElastiCacheIntegrationsClientConfiguration`, passed as
|
|
126
|
+
`client_configuration`. Every field has a default, so set only what you change. Cache policy
|
|
127
|
+
settings are sent to the cache through `aws.config`.
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
aws_elasticache_integration_client.install(
|
|
131
|
+
client=ddb,
|
|
132
|
+
endpoint="my-cache:6379",
|
|
133
|
+
cache_name="my-cache",
|
|
134
|
+
client_configuration=aws_elasticache_integration_client.ElastiCacheIntegrationsClientConfiguration(
|
|
135
|
+
cache_request_timeout=2000,
|
|
136
|
+
connection_timeout=5000,
|
|
137
|
+
fallback_duration=60,
|
|
138
|
+
cache_policy_overrides={"cached_tables": ["Users", "Sessions"]},
|
|
139
|
+
iam_token_refresh_delay=300,
|
|
140
|
+
),
|
|
141
|
+
)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
| Field | Default | Meaning |
|
|
145
|
+
|---|---|---|
|
|
146
|
+
| `cache_request_timeout` | 5000 ms | How long to wait for each ElastiCacheIntegrations request's reply. |
|
|
147
|
+
| `connection_timeout` | 5000 ms | How long to try at startup, and how long a request waits for reconnection after a connection is lost. |
|
|
148
|
+
| `fallback_duration` | `None` (indefinite) | How long requests may go to the origin service while there is no cache connection (see below). |
|
|
149
|
+
| `cache_policy_overrides` | `None` | Settings that change what ElastiCacheIntegrations caches: `cached_tables` and `cached_operations` allowlists, and the cache entry lifetimes. See below. |
|
|
150
|
+
| `cache_policy_timeout` | 3600 s | How long ElastiCacheIntegrations may use a cache policy without confirmation from the cache. |
|
|
151
|
+
| `iam_token_refresh_delay` | 300 s | When the IAM toolkit signs a replacement token in the background. |
|
|
152
|
+
|
|
153
|
+
Building `ElastiCacheIntegrationsClientConfiguration` raises `ElastiCacheIntegrationsConfigError` for a value that is not usable.
|
|
154
|
+
|
|
155
|
+
### Cache policy overrides
|
|
156
|
+
|
|
157
|
+
`cached_tables` and `cached_operations` are **allowlists**, and they intersect: only those
|
|
158
|
+
operations, on only those tables. Each one empty or absent means everything, so the example
|
|
159
|
+
above caches `Users` and `Sessions` and nothing else. There is no exclude form — to keep one
|
|
160
|
+
table out of the cache, name the tables that should be in it.
|
|
161
|
+
|
|
162
|
+
Lifetimes are set per category (`item_ttl`, `item_negative_ttl`, `query_ttl`, `scan_ttl`),
|
|
163
|
+
connection-wide at the top level or per table under `table_overrides`; a `table_overrides`
|
|
164
|
+
entry is settings only and never puts a table in scope.
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
cache_policy_overrides = {
|
|
168
|
+
"cached_tables": ["Users", "Sessions"],
|
|
169
|
+
"cached_operations": ["GetItem", "Query"],
|
|
170
|
+
"item_ttl": 500,
|
|
171
|
+
"item_negative_ttl": 0, # do not cache "this item does not exist"
|
|
172
|
+
"table_overrides": {"Users": {"item_ttl": 60}},
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
A value the cache does not allow is refused at connect time with
|
|
177
|
+
`ElastiCacheIntegrationsOverridesRejected`, rather than being quietly adjusted. A field name
|
|
178
|
+
the cache does not recognise is **ignored**, so a typo fails silently — the names above are
|
|
179
|
+
the whole set.
|
|
180
|
+
|
|
181
|
+
## IAM authentication
|
|
182
|
+
|
|
183
|
+
IAM token generation and refresh come from the Amazon ElastiCache developer toolkit, the
|
|
184
|
+
[`developer-toolkit-elasticache`](https://pypi.org/project/developer-toolkit-elasticache/) package on PyPI.
|
|
185
|
+
The toolkit validates and lowercases cache names and user IDs, re-reads the credentials for
|
|
186
|
+
every newly signed token, and owns the SigV4 signing contract. ElastiCacheIntegrations sends the bearer token
|
|
187
|
+
only in the TLS-protected `HELLO 3 AUTH` exchange; origin request signing remains owned by boto3.
|
|
188
|
+
|
|
189
|
+
The credentials are the ones behind the boto3 client, so the cache is authenticated as the same
|
|
190
|
+
principal as the requests, and rotation (SSO, assume-role, container, instance metadata) keeps
|
|
191
|
+
working because the credentials object refreshes itself. A client built with
|
|
192
|
+
`signature_version=UNSIGNED` carries none and is rejected.
|
|
193
|
+
|
|
194
|
+
`install()` creates a toolkit token manager. It caches the current token, signs a
|
|
195
|
+
replacement in the background after 300 seconds by default, and force-refreshes when a live
|
|
196
|
+
connection explicitly rejects the cached token. Set `iam_token_refresh_delay` to customize that
|
|
197
|
+
background signing point through `ElastiCacheIntegrationsClientConfiguration`; it must be greater than 0 and less
|
|
198
|
+
than 880 seconds, preserving the toolkit's 20-second safety margin on the 15-minute token.
|
|
199
|
+
|
|
200
|
+
Independently, ElastiCacheIntegrations sends `AUTH` on the live connection every 15 minutes to refresh the proxy's
|
|
201
|
+
forward-access session. A rejected background `AUTH` leaves the existing connection alive on its
|
|
202
|
+
previous authentication and is retried with backoff. Only a timeout or unexpected reply closes the
|
|
203
|
+
connection for FIFO safety. Closing the boto3 client stops both ElastiCacheIntegrations re-authentication and the
|
|
204
|
+
toolkit's token refresh.
|
|
205
|
+
|
|
206
|
+
## Reconnection and fallback
|
|
207
|
+
|
|
208
|
+
A lost connection is rebuilt in the background and retried until it succeeds. Right after the
|
|
209
|
+
loss, a request waits up to `connection_timeout` for the new connection. If the connection is not
|
|
210
|
+
back by then, the AWS SDK sends the request to the origin service using the application's own
|
|
211
|
+
credentials. The same timeout bounds startup; client creation fails if no connection is ready.
|
|
212
|
+
|
|
213
|
+
How long requests may fall back, counted from the end of `connection_timeout`, is controlled by
|
|
214
|
+
`fallback_duration`:
|
|
215
|
+
|
|
216
|
+
| `fallback_duration` | Behavior |
|
|
217
|
+
|---|---|
|
|
218
|
+
| `None` (default), or negative | Serve from the origin service indefinitely, so a cache outage never becomes an application outage. |
|
|
219
|
+
| `N > 0` | Serve from the origin service for N seconds, then raise `ElastiCacheIntegrationsCacheUnavailable`. |
|
|
220
|
+
| `0` | Never fall back — wait up to `connection_timeout` for a connection, then raise `ElastiCacheIntegrationsCacheUnavailable`. |
|
|
221
|
+
|
|
222
|
+
The window is **per outage, not a total budget**: `fallback_duration=60` allows 60 seconds of
|
|
223
|
+
fallback each time the connection is lost, and a connection that keeps flapping gets a fresh 60
|
|
224
|
+
seconds after every successful reconnect.
|
|
225
|
+
|
|
226
|
+
`aws_elasticache_integration_client.ElastiCacheIntegrationsCacheUnavailable` subclasses botocore's `ConnectionClosedError`, so it is retryable and
|
|
227
|
+
an application's existing `except botocore...` blocks already catch it. Retryable cuts both ways:
|
|
228
|
+
under the SDK's default retry mode a raised request is retried, which is usually what you want — a
|
|
229
|
+
retry after backoff can land once the connection is back. With `fallback_duration=0`, a routed
|
|
230
|
+
request waits only for the part of `connection_timeout` left in the current outage. Later retries in
|
|
231
|
+
the same outage do not restart that wait.
|
|
232
|
+
|
|
233
|
+
When there is no live cache connection, the request has not been sent and can safely pass through
|
|
234
|
+
for any operation while the fallback window remains open. After a request is sent, origin fallback
|
|
235
|
+
is allowed only when the connection drops and the operation is in the shared replay-safe catalog.
|
|
236
|
+
While the connection remains healthy, `ORIGIN_ERROR` becomes a botocore-retryable error only for a
|
|
237
|
+
cataloged operation. `AUTH_ERROR` closes the stale connection and passes the rejected
|
|
238
|
+
request through while reconnection obtains fresh authentication. With `fallback_duration=0`, the
|
|
239
|
+
rejected request raises `ElastiCacheIntegrationsCacheUnavailable` at once instead. Other RESP
|
|
240
|
+
errors, malformed replies, and failures for non-idempotent operations propagate without origin
|
|
241
|
+
fallback.
|
|
242
|
+
|
|
243
|
+
## Cache policy timeout
|
|
244
|
+
|
|
245
|
+
ElastiCacheIntegrations automatically confirms the resolved cache policy in the background through `aws.config`.
|
|
246
|
+
A new policy replaces the current one. An unchanged reply confirms that the current policy is still
|
|
247
|
+
valid. Both replies restart the timeout.
|
|
248
|
+
|
|
249
|
+
If confirmation fails, ElastiCacheIntegrations keeps using the last confirmed policy. That tolerance is bounded by
|
|
250
|
+
`cache_policy_timeout`, one hour by default. After the timeout, the next failed confirmation drops
|
|
251
|
+
the connection so a replacement can fetch a current policy. Requests follow the `fallback_duration`
|
|
252
|
+
rules while the connection is being replaced.
|
|
253
|
+
|
|
254
|
+
## Next steps:
|
|
255
|
+
|
|
256
|
+
- **Observability.** Reconnection and config staleness are logged but emit no metrics, so under the
|
|
257
|
+
default `fallback_duration` a cache outage has no symptom other than the origin service's bill.
|
|
258
|
+
- **Detecting a silently dead peer.** A peer that vanishes without closing the socket is noticed only
|
|
259
|
+
when the next request times out. Closing that gap needs a periodic health check.
|
|
260
|
+
- **IAM authentication validation.** Exercise the toolkit-backed flow against a real IAM-enabled
|
|
261
|
+
cache in addition to the hermetic mock-cache coverage.
|
|
262
|
+
- **Public TTL / NTTL controls.** TTL/NTTL policy is resolved server-side from the
|
|
263
|
+
`aws.config` overrides; the public API does not expose per-table or per-request TTL
|
|
264
|
+
overrides yet.
|