aury-boot 0.0.40__py3-none-any.whl → 0.0.42__py3-none-any.whl

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.
@@ -0,0 +1,255 @@
1
+ """Redis Cluster JobStore for APScheduler.
2
+
3
+ 支持 Redis Cluster 的任务存储,使用 redis-cluster:// URL 格式。
4
+
5
+ 使用示例:
6
+ from aury.boot.infrastructure.scheduler.jobstores import RedisClusterJobStore
7
+
8
+ # 使用 URL(推荐)
9
+ jobstore = RedisClusterJobStore(
10
+ url="redis-cluster://password@redis-cluster.example.com:6379"
11
+ )
12
+
13
+ # 使用参数
14
+ jobstore = RedisClusterJobStore(
15
+ host="redis-cluster.example.com",
16
+ port=6379,
17
+ password="password",
18
+ )
19
+
20
+ scheduler = SchedulerManager.get_instance(
21
+ jobstores={"default": jobstore}
22
+ )
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ import pickle
28
+ from datetime import datetime, timezone
29
+ from typing import TYPE_CHECKING, Any
30
+ from urllib.parse import parse_qs, urlparse
31
+
32
+ from apscheduler.job import Job
33
+ from apscheduler.jobstores.base import BaseJobStore, ConflictingIdError, JobLookupError
34
+ from apscheduler.util import datetime_to_utc_timestamp, utc_timestamp_to_datetime
35
+
36
+ try:
37
+ from redis.cluster import RedisCluster
38
+ except ImportError as exc:
39
+ raise ImportError(
40
+ "RedisClusterJobStore requires redis[cluster] installed: "
41
+ "pip install 'redis[cluster]'"
42
+ ) from exc
43
+
44
+ if TYPE_CHECKING:
45
+ from apscheduler.schedulers.base import BaseScheduler
46
+
47
+
48
+ class RedisClusterJobStore(BaseJobStore):
49
+ """Redis Cluster 任务存储。
50
+
51
+ 与 APScheduler 的 RedisJobStore 兼容,但使用 RedisCluster 客户端。
52
+ 使用 hash tag 确保 jobs_key 和 run_times_key 在同一个 slot。
53
+
54
+ Args:
55
+ url: Redis Cluster URL,格式: redis-cluster://[password@]host:port
56
+ 或标准格式: redis://[password@]host:port(会自动识别为集群)
57
+ jobs_key: 存储任务的 key,默认 "{apscheduler}.jobs"
58
+ run_times_key: 存储运行时间的 key,默认 "{apscheduler}.run_times"
59
+ pickle_protocol: pickle 序列化协议版本
60
+ **connect_args: 传递给 RedisCluster 的其他参数
61
+ """
62
+
63
+ def __init__(
64
+ self,
65
+ url: str | None = None,
66
+ jobs_key: str = "{apscheduler}.jobs",
67
+ run_times_key: str = "{apscheduler}.run_times",
68
+ pickle_protocol: int = pickle.HIGHEST_PROTOCOL,
69
+ **connect_args: Any,
70
+ ) -> None:
71
+ super().__init__()
72
+
73
+ if not jobs_key:
74
+ raise ValueError('The "jobs_key" parameter must not be empty')
75
+ if not run_times_key:
76
+ raise ValueError('The "run_times_key" parameter must not be empty')
77
+
78
+ self.pickle_protocol = pickle_protocol
79
+ self.jobs_key = jobs_key
80
+ self.run_times_key = run_times_key
81
+
82
+ if url:
83
+ # 解析 URL
84
+ self.redis = self._create_client_from_url(url, **connect_args)
85
+ else:
86
+ # 使用参数直接连接
87
+ self.redis = RedisCluster(**connect_args)
88
+
89
+ def _create_client_from_url(self, url: str, **kwargs: Any) -> RedisCluster:
90
+ """从 URL 创建 RedisCluster 客户端。
91
+
92
+ 支持格式:
93
+ - redis-cluster://password@host:port (密码在用户名位置)
94
+ - redis-cluster://:password@host:port (标准格式)
95
+ - redis-cluster://username:password@host:port (ACL 模式)
96
+ """
97
+ # 统一转换为 redis:// 格式供解析
98
+ if url.startswith("redis-cluster://"):
99
+ url = url.replace("redis-cluster://", "redis://", 1)
100
+
101
+ parsed = urlparse(url)
102
+
103
+ # 提取连接参数
104
+ host = parsed.hostname or "localhost"
105
+ port = parsed.port or 6379
106
+ username = parsed.username
107
+ password = parsed.password
108
+
109
+ # 处理 password@host 格式(密码在用户名位置)
110
+ if username and not password:
111
+ password = username
112
+ username = None
113
+
114
+ # 解析查询参数
115
+ query_params = parse_qs(parsed.query)
116
+
117
+ # 构建连接参数
118
+ connect_kwargs: dict[str, Any] = {
119
+ "host": host,
120
+ "port": port,
121
+ **kwargs,
122
+ }
123
+
124
+ if username:
125
+ connect_kwargs["username"] = username
126
+ if password:
127
+ connect_kwargs["password"] = password
128
+
129
+ # 处理常见查询参数
130
+ if "decode_responses" in query_params:
131
+ connect_kwargs["decode_responses"] = query_params["decode_responses"][0].lower() == "true"
132
+
133
+ return RedisCluster(**connect_kwargs)
134
+
135
+ def lookup_job(self, job_id: str) -> Job | None:
136
+ """查找任务。"""
137
+ job_state = self.redis.hget(self.jobs_key, job_id)
138
+ return self._reconstitute_job(job_state) if job_state else None
139
+
140
+ def get_due_jobs(self, now: datetime) -> list[Job]:
141
+ """获取到期的任务。"""
142
+ timestamp = datetime_to_utc_timestamp(now)
143
+ job_ids = self.redis.zrangebyscore(self.run_times_key, 0, timestamp)
144
+ if job_ids:
145
+ job_states = self.redis.hmget(self.jobs_key, *job_ids)
146
+ return self._reconstitute_jobs(zip(job_ids, job_states))
147
+ return []
148
+
149
+ def get_next_run_time(self) -> datetime | None:
150
+ """获取下次运行时间。"""
151
+ next_run_time = self.redis.zrange(self.run_times_key, 0, 0, withscores=True)
152
+ if next_run_time:
153
+ return utc_timestamp_to_datetime(next_run_time[0][1])
154
+ return None
155
+
156
+ def get_all_jobs(self) -> list[Job]:
157
+ """获取所有任务。"""
158
+ job_states = self.redis.hgetall(self.jobs_key)
159
+ jobs = self._reconstitute_jobs(job_states.items())
160
+ paused_sort_key = datetime(9999, 12, 31, tzinfo=timezone.utc)
161
+ return sorted(jobs, key=lambda job: job.next_run_time or paused_sort_key)
162
+
163
+ def add_job(self, job: Job) -> None:
164
+ """添加任务。"""
165
+ if self.redis.hexists(self.jobs_key, job.id):
166
+ raise ConflictingIdError(job.id)
167
+
168
+ with self.redis.pipeline() as pipe:
169
+ pipe.hset(
170
+ self.jobs_key,
171
+ job.id,
172
+ pickle.dumps(job.__getstate__(), self.pickle_protocol),
173
+ )
174
+ if job.next_run_time:
175
+ pipe.zadd(
176
+ self.run_times_key,
177
+ {job.id: datetime_to_utc_timestamp(job.next_run_time)},
178
+ )
179
+ pipe.execute()
180
+
181
+ def update_job(self, job: Job) -> None:
182
+ """更新任务。"""
183
+ if not self.redis.hexists(self.jobs_key, job.id):
184
+ raise JobLookupError(job.id)
185
+
186
+ with self.redis.pipeline() as pipe:
187
+ pipe.hset(
188
+ self.jobs_key,
189
+ job.id,
190
+ pickle.dumps(job.__getstate__(), self.pickle_protocol),
191
+ )
192
+ if job.next_run_time:
193
+ pipe.zadd(
194
+ self.run_times_key,
195
+ {job.id: datetime_to_utc_timestamp(job.next_run_time)},
196
+ )
197
+ else:
198
+ pipe.zrem(self.run_times_key, job.id)
199
+ pipe.execute()
200
+
201
+ def remove_job(self, job_id: str) -> None:
202
+ """移除任务。"""
203
+ if not self.redis.hexists(self.jobs_key, job_id):
204
+ raise JobLookupError(job_id)
205
+
206
+ with self.redis.pipeline() as pipe:
207
+ pipe.hdel(self.jobs_key, job_id)
208
+ pipe.zrem(self.run_times_key, job_id)
209
+ pipe.execute()
210
+
211
+ def remove_all_jobs(self) -> None:
212
+ """移除所有任务。"""
213
+ with self.redis.pipeline() as pipe:
214
+ pipe.delete(self.jobs_key)
215
+ pipe.delete(self.run_times_key)
216
+ pipe.execute()
217
+
218
+ def shutdown(self) -> None:
219
+ """关闭连接。"""
220
+ self.redis.close()
221
+
222
+ def _reconstitute_job(self, job_state: bytes) -> Job:
223
+ """重建任务对象。"""
224
+ state = pickle.loads(job_state)
225
+ job = Job.__new__(Job)
226
+ job.__setstate__(state)
227
+ job._scheduler = self._scheduler
228
+ job._jobstore_alias = self._alias
229
+ return job
230
+
231
+ def _reconstitute_jobs(self, job_states: Any) -> list[Job]:
232
+ """重建多个任务对象。"""
233
+ jobs = []
234
+ failed_job_ids = []
235
+
236
+ for job_id, job_state in job_states:
237
+ try:
238
+ jobs.append(self._reconstitute_job(job_state))
239
+ except Exception:
240
+ self._logger.exception(
241
+ 'Unable to restore job "%s" -- removing it', job_id
242
+ )
243
+ failed_job_ids.append(job_id)
244
+
245
+ # 移除无法恢复的任务
246
+ if failed_job_ids:
247
+ with self.redis.pipeline() as pipe:
248
+ pipe.hdel(self.jobs_key, *failed_job_ids)
249
+ pipe.zrem(self.run_times_key, *failed_job_ids)
250
+ pipe.execute()
251
+
252
+ return jobs
253
+
254
+ def __repr__(self) -> str:
255
+ return f"<{self.__class__.__name__}>"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aury-boot
3
- Version: 0.0.40
3
+ Version: 0.0.42
4
4
  Summary: Aury Boot - 基于 FastAPI 生态的企业级 API 开发框架
5
5
  Requires-Python: >=3.13
6
6
  Requires-Dist: aiohttp>=3.11.0
@@ -28,6 +28,7 @@ Requires-Dist: aiosqlite>=0.21.0; extra == 'all'
28
28
  Requires-Dist: apscheduler>=3.11.1; extra == 'all'
29
29
  Requires-Dist: asyncpg>=0.31.0; extra == 'all'
30
30
  Requires-Dist: aury-sdk-storage[aws]>=0.0.1; extra == 'all'
31
+ Requires-Dist: coredis>=5.6.0; extra == 'all'
31
32
  Requires-Dist: dramatiq>=1.18.0; extra == 'all'
32
33
  Requires-Dist: pika>=1.3.2; extra == 'all'
33
34
  Requires-Dist: psutil>=7.0.0; extra == 'all'
@@ -35,6 +36,8 @@ Requires-Dist: pyroscope-io>=0.8.7; extra == 'all'
35
36
  Requires-Dist: redis>=7.1.0; extra == 'all'
36
37
  Provides-Extra: broadcaster
37
38
  Requires-Dist: broadcaster[redis]>=0.3.1; extra == 'broadcaster'
39
+ Provides-Extra: channel-cluster
40
+ Requires-Dist: coredis>=5.6.0; extra == 'channel-cluster'
38
41
  Provides-Extra: dev
39
42
  Requires-Dist: httpx>=0.28.1; extra == 'dev'
40
43
  Requires-Dist: mypy>=1.19.0; extra == 'dev'
@@ -68,6 +71,7 @@ Requires-Dist: aiosqlite>=0.21.0; extra == 'recommended'
68
71
  Requires-Dist: apscheduler>=3.11.1; extra == 'recommended'
69
72
  Requires-Dist: asyncpg>=0.31.0; extra == 'recommended'
70
73
  Requires-Dist: aury-sdk-storage[aws]>=0.0.1; extra == 'recommended'
74
+ Requires-Dist: coredis>=5.6.0; extra == 'recommended'
71
75
  Requires-Dist: dramatiq>=1.18.0; extra == 'recommended'
72
76
  Requires-Dist: opentelemetry-api>=1.25.0; extra == 'recommended'
73
77
  Requires-Dist: opentelemetry-instrumentation-aiohttp-client>=0.46b0; extra == 'recommended'
@@ -1,5 +1,5 @@
1
1
  aury/boot/__init__.py,sha256=pCno-EInnpIBa1OtxNYF-JWf9j95Cd2h6vmu0xqa_-4,1791
2
- aury/boot/_version.py,sha256=iVCKwk3ALZWN3TArFywN2NsKO1DSIjrjwe22g3qygd0,706
2
+ aury/boot/_version.py,sha256=f7OCYKa3JxU7ivIZuRhrUjsUfgAkieENmQhgCn-5SzY,706
3
3
  aury/boot/application/__init__.py,sha256=I2KqNVdYg2q5nlOXr0TtFGyHmhj4oWdaR6ZB73Mwg7Y,3041
4
4
  aury/boot/application/adapter/__init__.py,sha256=e1bcSb1bxUMfofTwiCuHBZJk5-STkMCWPF2EJXHQ7UU,3976
5
5
  aury/boot/application/adapter/base.py,sha256=Ar_66fiHPDEmV-1DKnqXKwc53p3pozG31bgTJTEUriY,15763
@@ -9,12 +9,12 @@ aury/boot/application/adapter/exceptions.py,sha256=Kzm-ytRxdUnSMIcWCSOHPxo4Jh_A6
9
9
  aury/boot/application/adapter/http.py,sha256=aKwjlelW9BeH1FFF_MA0o8R5bnKdWYoG6VKjJMB81JA,11042
10
10
  aury/boot/application/app/__init__.py,sha256=I8FfCKDuDQsGzAK6BevyfdtAwieMUVYu6qgVQzBazpE,830
11
11
  aury/boot/application/app/base.py,sha256=oLktBx008BzLmRRwUO4AvLVD-gEpJOx-tS-bip7lFfU,21674
12
- aury/boot/application/app/components.py,sha256=rMNc5XU6aIH8fjg_gLFb1C1W9RYKxcjQX-WD_D0M4Rg,36889
12
+ aury/boot/application/app/components.py,sha256=zWWDZQKxdH6ZlwlUywRLJSWTpNNys1NQouKMgK2B0ho,37526
13
13
  aury/boot/application/app/middlewares.py,sha256=BXe2H14FHzJUVpQM6DZUm-zfZRXSXIi1QIZ4_3izfHw,3306
14
14
  aury/boot/application/app/startup.py,sha256=DHKt3C2G7V5XfFr1SQMl14tNzcuDd9MqUVAxi274HDQ,7873
15
15
  aury/boot/application/config/__init__.py,sha256=Dd-myRSBCM18DXXsi863h0cJG5VFrI10xMRtjnvelGo,1894
16
16
  aury/boot/application/config/multi_instance.py,sha256=RXSp-xP8-bKMDEhq3SeL7T3lS8-vpRlvBEVBuZVjVK4,6475
17
- aury/boot/application/config/settings.py,sha256=Ia-RXXEdgxiCZCNksUIzEK1qG9qQvF81SnSW_YqaN5A,40453
17
+ aury/boot/application/config/settings.py,sha256=Oaty7koO0ynUi636RFQvRwrRZRLPzv69f91U-nOkddU,40746
18
18
  aury/boot/application/constants/__init__.py,sha256=DCXs13_VVaQWHqO-qpJoZwRd7HIexiirtw_nu8msTXE,340
19
19
  aury/boot/application/constants/components.py,sha256=I4SlsF2DpSzMiLsi1wVrEmdHn4yV5J2h3ikMQqufPmM,1120
20
20
  aury/boot/application/constants/scheduler.py,sha256=S77FBIvHlyruvlabRWZJ2J1YAs2xWXPQI2yuGdGUDNA,471
@@ -143,19 +143,21 @@ aury/boot/infrastructure/cache/exceptions.py,sha256=KZsFIHXW3_kOh_KB93EVZJKbiDvD
143
143
  aury/boot/infrastructure/cache/factory.py,sha256=aF74JoiiSKFgctqqh2Z8OtGRS2Am_ou-I40GyygLzC0,2489
144
144
  aury/boot/infrastructure/cache/manager.py,sha256=2jlshbO4NqpPxH-8DBiMFNAvWuZUI3atUCsw9GGlzc8,16807
145
145
  aury/boot/infrastructure/cache/memory.py,sha256=qGhLKKjGsEUHjVRFMV6A33MB_1iPaKCEEkT6VFrLkQY,9832
146
- aury/boot/infrastructure/cache/redis.py,sha256=MxLwqnBrPWmkS_AGDq4hKfPlBrF358cq_nKbUlP-JYE,8085
147
- aury/boot/infrastructure/channel/__init__.py,sha256=NmjddenZPz1Dcl0glwIF1Xn9gxBzvGvlOlzhV3eEnEQ,664
148
- aury/boot/infrastructure/channel/base.py,sha256=TDiP7pXyd2ixiOM3cbxqCSOluGLTkmLCa8pv-KyQ0jo,2941
149
- aury/boot/infrastructure/channel/manager.py,sha256=GT6eG6PglduKAr23i1PSmjjTQsALvGGoLjYiQ33aZiw,7488
150
- aury/boot/infrastructure/channel/backends/__init__.py,sha256=NcXG8_KAqy1SiGUs2z_KvkS90jMfLJ6bzyYK4Jw4qCg,107
146
+ aury/boot/infrastructure/cache/redis.py,sha256=NGtowB2DNXC1AX5v4FK9RRRl6wFZxoOWi3d6oiUzjvo,10485
147
+ aury/boot/infrastructure/channel/__init__.py,sha256=zv3dNH4By8h-5Fksi18LFJVf5cXBmj0M49DjTfQL2w4,712
148
+ aury/boot/infrastructure/channel/base.py,sha256=xE_7vtgSB06PIq6HPh59MXXisjBuz530NmlnMwQxU5Q,3049
149
+ aury/boot/infrastructure/channel/manager.py,sha256=pTXhWTjRh83ifX9bKlsD4t5w1pZQOZszGbiy4wBYfJ8,7906
150
+ aury/boot/infrastructure/channel/backends/__init__.py,sha256=qRA8JuAueQXRfcqJSl-M2a1sRNscPjCQBgVmWn3DFu4,185
151
151
  aury/boot/infrastructure/channel/backends/broadcaster.py,sha256=y8eKx6X6Iy9a_5vnLMm5gjqkq05SmJEWESw1-x0lIFg,4771
152
+ aury/boot/infrastructure/channel/backends/redis_cluster.py,sha256=3OfVpGZ7-IfXiOuF8XnS1LXFemkIpEbvWUP9BZZRvTM,4125
153
+ aury/boot/infrastructure/channel/backends/redis_cluster_channel.py,sha256=MAlo1mnyQzjhK1FwxeTiMvz_RpFjVuH3AgKKhAcH8Rs,4949
152
154
  aury/boot/infrastructure/clients/__init__.py,sha256=1ANMejb3RrBgaR-jq-dsxJ0kQDRHz5jV-QvdUNcf_ok,435
153
155
  aury/boot/infrastructure/clients/rabbitmq/__init__.py,sha256=cnU-W7jOcAgp_FvsY9EipNCeJzeA9gHLRuZ0yQZE2DI,200
154
156
  aury/boot/infrastructure/clients/rabbitmq/config.py,sha256=YmvNiISpqNt-LE2CrpzmxCgaEgYna7IbOfUSnA0B4T0,1239
155
157
  aury/boot/infrastructure/clients/rabbitmq/manager.py,sha256=a3Op0yN2DICnoqxOVb0DVT9RnoF8laN2EutOsOSWzWA,9659
156
158
  aury/boot/infrastructure/clients/redis/__init__.py,sha256=HGZVfcWmOPeiAk-rJ8Yun7N5CQiPlGFofdByvl8Uqso,613
157
159
  aury/boot/infrastructure/clients/redis/config.py,sha256=KfC2R7bcQ91zjTp8Q_S7j3ZemDLdejUYc3CrWsJlpNM,1421
158
- aury/boot/infrastructure/clients/redis/manager.py,sha256=Dmfu6OWGe_PrBr9wbOhl3suUpuKMUJDnCz6xW-rU4fQ,8538
160
+ aury/boot/infrastructure/clients/redis/manager.py,sha256=lJiO4ChczgSb4MJLjFmESJtRxK_dkZWgvh8E9Wt3wc0,11103
159
161
  aury/boot/infrastructure/database/__init__.py,sha256=MsHNyrJ2CZJT-lbVZzOAJ0nFfFEmHrJqC0zw-cFS768,888
160
162
  aury/boot/infrastructure/database/config.py,sha256=5LYy4DuLL0XNjVnX2HUcrMh3c71eeZa-vWGM8QCkL0U,1408
161
163
  aury/boot/infrastructure/database/exceptions.py,sha256=hUjsU23c0eMwogSDrKq_bQ6zvnY7PQSGaitbCEhhDZQ,766
@@ -179,10 +181,10 @@ aury/boot/infrastructure/monitoring/alerting/manager.py,sha256=vdWox9Pnjl_0IIE6w
179
181
  aury/boot/infrastructure/monitoring/alerting/rules.py,sha256=FdyGOolQJF31fN_9mqRGi9i_x2JqtoHEOkNOcPyO07o,6124
180
182
  aury/boot/infrastructure/monitoring/alerting/notifiers/__init__.py,sha256=dsfxThPHO_Ofb3Wo_dYlL8HvP_N63pb_S_UXm_qSxF8,321
181
183
  aury/boot/infrastructure/monitoring/alerting/notifiers/base.py,sha256=_RXZMzWX-YeTG0Up1U8CwK8ADfX34dd0Sh56ugfqOWM,1462
182
- aury/boot/infrastructure/monitoring/alerting/notifiers/feishu.py,sha256=7IdJruRsapvr4aWWnil8ijYu81wIJ8ISH2IE3Dk0wO4,8310
184
+ aury/boot/infrastructure/monitoring/alerting/notifiers/feishu.py,sha256=XWiyAcoKzg-1lOjIUflowFVxowW4nEXAQoOvBM9i6jY,8403
183
185
  aury/boot/infrastructure/monitoring/alerting/notifiers/webhook.py,sha256=2PlS95sIS1HkZaedZW-tAMYjLquk1YWpPFjMMYCBM4M,3644
184
186
  aury/boot/infrastructure/monitoring/health/__init__.py,sha256=nqwFFXl6J9yTfQa1JLjQDs4hS4qSVEeA4w07JWdt4jM,7305
185
- aury/boot/infrastructure/monitoring/profiling/__init__.py,sha256=SmeGZzb-vHIwmt4l_oDzZS35Y-Qfei8kU7e2K7-AufY,20169
187
+ aury/boot/infrastructure/monitoring/profiling/__init__.py,sha256=9gGTPk7VnpeiGyMhfo7JkrfVrbHZA12vXmfvds41r44,24491
186
188
  aury/boot/infrastructure/monitoring/tracing/__init__.py,sha256=YizkpnhY-bcUUcd8YaDzUsluMflhNOH1dAKdVtkW05U,1287
187
189
  aury/boot/infrastructure/monitoring/tracing/context.py,sha256=s_k2MzNl4LDDpei9xUP6TFW5BwZneoQg44RPaw95jac,978
188
190
  aury/boot/infrastructure/monitoring/tracing/logging.py,sha256=gzuKa1ZiyY4z06fHNTbjgZasS6mLftSEaZQQ-Z6J_RE,2041
@@ -196,9 +198,11 @@ aury/boot/infrastructure/mq/backends/__init__.py,sha256=10nggw2V-AzuZ1vvzq_ksoXR
196
198
  aury/boot/infrastructure/mq/backends/rabbitmq.py,sha256=0NWgPKEwtbmI63EVvKINdfXXDNyOvuOOP9LlBzqH91E,5493
197
199
  aury/boot/infrastructure/mq/backends/redis.py,sha256=B89U7mqIceUsCXE4G3u1u6aFM9hv4mmLLwuCYq1T9tQ,5281
198
200
  aury/boot/infrastructure/mq/backends/redis_stream.py,sha256=p2WTj10-zbxQ_2NPU97w-n4DZ8KSHhLjqcnplLPCw4U,14761
199
- aury/boot/infrastructure/scheduler/__init__.py,sha256=eTRJ5dSPcKvyFvLVtraoQteXTTDDGwIrmw06J2hoNdA,323
201
+ aury/boot/infrastructure/scheduler/__init__.py,sha256=ji_K1OePMHt4CIFr168LGEbSuX8ybgrden-W75b0NdI,395
200
202
  aury/boot/infrastructure/scheduler/exceptions.py,sha256=ROltrhSctVWA-6ulnjuYeHAk3ZF-sykDoesuierYzew,634
201
203
  aury/boot/infrastructure/scheduler/manager.py,sha256=wUxMRGXpoAwjHnB4u7BKnzJbiPZE5sovuLPrgLoQYb4,23753
204
+ aury/boot/infrastructure/scheduler/jobstores/__init__.py,sha256=tsHS7YzQsmOOjLCqxjvLFET6J9kLqKvT5Fn-DdIz5-w,174
205
+ aury/boot/infrastructure/scheduler/jobstores/redis_cluster.py,sha256=HKXoAo3E7yffE8o2PGhvANiJkR03UUU994CIzZZ4AP4,8927
202
206
  aury/boot/infrastructure/storage/__init__.py,sha256=bA-n3v2S1FX6XsQbLqt0hkgx512MjUn_b8kJo53G6gA,1238
203
207
  aury/boot/infrastructure/storage/base.py,sha256=X9aswSMWtKZ6TdG5Rrh6qJpqIVLt1QcFkQAKdyUWPi0,5039
204
208
  aury/boot/infrastructure/storage/exceptions.py,sha256=Av1r94bRkeeeDo6vgAD9e_9YA9Ge6D7F2U1qzUs-8FE,622
@@ -214,7 +218,7 @@ aury/boot/testing/client.py,sha256=KOg1EemuIVsBG68G5y0DjSxZGcIQVdWQ4ASaHE3o1R0,4
214
218
  aury/boot/testing/factory.py,sha256=8GvwX9qIDu0L65gzJMlrWB0xbmJ-7zPHuwk3eECULcg,5185
215
219
  aury/boot/toolkit/__init__.py,sha256=AcyVb9fDf3CaEmJPNkWC4iGv32qCPyk4BuFKSuNiJRQ,334
216
220
  aury/boot/toolkit/http/__init__.py,sha256=5bv4Ntz1sbNFhP9zPLBDhB536ZX1CKIAOp-kQSKMRQ0,14161
217
- aury_boot-0.0.40.dist-info/METADATA,sha256=8deP0tWBoSZqiF32QRvpvTkeNS0J3YEReU9HvER9TIw,8989
218
- aury_boot-0.0.40.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
219
- aury_boot-0.0.40.dist-info/entry_points.txt,sha256=f9KXEkDIGc0BGkgBvsNx_HMz9VhDjNxu26q00jUpDwQ,49
220
- aury_boot-0.0.40.dist-info/RECORD,,
221
+ aury_boot-0.0.42.dist-info/METADATA,sha256=XD_XzyPx56L6W8X2ZBAbgp1naPm4NKwhq1tMH_Aq5FM,9179
222
+ aury_boot-0.0.42.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
223
+ aury_boot-0.0.42.dist-info/entry_points.txt,sha256=f9KXEkDIGc0BGkgBvsNx_HMz9VhDjNxu26q00jUpDwQ,49
224
+ aury_boot-0.0.42.dist-info/RECORD,,