Skip to content

Commit 6249a20

Browse files
committed
fix: use custom integrations for context-independent use (#62)
1 parent 470761b commit 6249a20

File tree

18 files changed

+145
-48
lines changed

18 files changed

+145
-48
lines changed

src/ttt/infrastructure/adapters/game_tasks.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from ttt.application.game.game.ports.game_tasks import GameTasks
55
from ttt.infrastructure.taskiq.tasks.make_ai_move_in_game_task import (
6-
make_ai_move_in_game_broker_task,
6+
make_ai_move_in_game_task,
77
)
88

99

@@ -16,4 +16,4 @@ async def make_ai_move(
1616
ai_id: UUID,
1717
/,
1818
) -> None:
19-
await make_ai_move_in_game_broker_task.kiq(user_id, game_id, ai_id)
19+
await make_ai_move_in_game_task.kiq(user_id, game_id, ai_id)

src/ttt/infrastructure/dishka/__init__.py

Whitespace-only changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from collections.abc import Mapping
2+
from typing import Any, Protocol
3+
4+
from dishka.async_container import AsyncContextWrapper
5+
6+
7+
class NextContainer(Protocol):
8+
def __call__(self, context: Mapping[Any, Any] = {}) -> AsyncContextWrapper:
9+
...
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from typing import Any
2+
3+
from dishka.integrations.taskiq import CONTAINER_NAME
4+
from taskiq import TaskiqMessage, TaskiqMiddleware, TaskiqResult
5+
6+
from ttt.infrastructure.dishka.next_container import NextContainer
7+
8+
9+
class TaskiqNextContainerMiddleware(TaskiqMiddleware):
10+
def __init__(self, next_container: NextContainer) -> None:
11+
super().__init__()
12+
self._next_container = next_container
13+
14+
async def pre_execute(
15+
self,
16+
message: TaskiqMessage,
17+
) -> TaskiqMessage:
18+
next_container = self._next_container({TaskiqMessage: message})
19+
20+
container = await next_container.__aenter__() # noqa: PLC2801
21+
message.labels[CONTAINER_NAME] = container
22+
return message
23+
24+
async def on_error(
25+
self,
26+
message: TaskiqMessage, # noqa: ARG002
27+
result: TaskiqResult[Any],
28+
exception: BaseException, # noqa: ARG002
29+
) -> None:
30+
if CONTAINER_NAME in result.labels:
31+
await result.labels[CONTAINER_NAME].close()
32+
del result.labels[CONTAINER_NAME]
33+
34+
async def post_execute(
35+
self,
36+
message: TaskiqMessage, # noqa: ARG002
37+
result: TaskiqResult[Any],
38+
) -> None:
39+
if CONTAINER_NAME in result.labels:
40+
await result.labels[CONTAINER_NAME].close()
41+
del result.labels[CONTAINER_NAME]

src/ttt/infrastructure/taskiq/tasks/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
complete_stars_purchase_payment_task,
44
)
55
from ttt.infrastructure.taskiq.tasks.make_ai_move_in_game_task import (
6-
make_ai_move_in_game_broker_task,
6+
make_ai_move_in_game_task,
77
)

src/ttt/infrastructure/taskiq/tasks/complete_stars_purchase_payment_task.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313

1414
@nats_tasks.task(
15+
task_name="stars_purchase-stars_purchase-complete_stars_purchase_payment",
1516
subject="stars_purchase.stars_purchase.complete_stars_purchase_payment",
1617
pull_subscribe=PullSubscribe(lambda js, subject: js.pull_subscribe(
1718
subject,

src/ttt/infrastructure/taskiq/tasks/make_ai_move_in_game_task.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010

1111
@nats_tasks.task(
12+
task_name="game-game-make_ai_move_in_game",
1213
subject="game.game.make_ai_move_in_game",
1314
pull_subscribe=PullSubscribe(lambda js, subject: js.pull_subscribe(
1415
subject,
@@ -17,7 +18,7 @@
1718
)),
1819
)
1920
@inject(patch_module=True)
20-
async def make_ai_move_in_game_broker_task(
21+
async def make_ai_move_in_game_task(
2122
user_id: int,
2223
game_id: UUID,
2324
ai_id: UUID,

src/ttt/infrastructure/taskiq/worker.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
from types import TracebackType
44
from typing import Self
55

6-
from dishka import AsyncContainer
7-
from dishka.integrations.taskiq import setup_dishka
86
from taskiq.receiver import Receiver
97

108

@@ -19,10 +17,7 @@ async def __aenter__(self) -> Self:
1917
await self._task_group.__aenter__()
2018
return self
2119

22-
async def __call__(self, container: AsyncContainer) -> None:
23-
for receiver in self._receivers:
24-
setup_dishka(container, receiver.broker)
25-
20+
async def __call__(self) -> None:
2621
await gather(*(
2722
receiver.broker.startup()
2823
for receiver in self._receivers
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from collections.abc import Mapping
2+
from dataclasses import dataclass
3+
from typing import Any
4+
5+
from dishka import AsyncContainer
6+
from dishka.async_container import AsyncContextWrapper
7+
8+
from ttt.infrastructure.dishka.next_container import NextContainer
9+
10+
11+
@dataclass
12+
class NextContainerWithFilledContext(NextContainer):
13+
_root_container: AsyncContainer
14+
_context_type_hints: tuple[Any, ...]
15+
16+
def __call__(
17+
self, context: Mapping[Any, Any] = {},
18+
) -> AsyncContextWrapper:
19+
return self._root_container(self._filled_context(context))
20+
21+
def _filled_context(self, context: Mapping[Any, Any]) -> dict[Any, Any]:
22+
return {
23+
hint | None: context.get(hint)
24+
for hint in self._context_type_hints
25+
}

src/ttt/main/tg_bot/di.py

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
FromComponent,
2020
Provider,
2121
Scope,
22+
from_context,
2223
provide,
2324
)
2425
from dishka.integrations.aiogram import AiogramMiddlewareData
@@ -165,15 +166,11 @@ class NoMessageInEventError(Exception):
165166

166167

167168
class PresentationProvider(Provider):
168-
@provide(scope=Scope.REQUEST)
169-
def provide_event(self, event: TelegramObject) -> TelegramObject | None:
170-
return event
171-
172-
@provide(scope=Scope.REQUEST)
173-
def provide_aiogram_middleware_data(
174-
self, data: AiogramMiddlewareData,
175-
) -> AiogramMiddlewareData | None:
176-
return data
169+
provide_aiogram_middleware_data = from_context(
170+
AiogramMiddlewareData | None,
171+
scope=Scope.REQUEST,
172+
)
173+
provide_event = from_context(TelegramObject | None, scope=Scope.REQUEST)
177174

178175
@provide(scope=Scope.APP)
179176
def provide_strage(self, redis: Redis) -> BaseStorage:
@@ -347,13 +344,6 @@ def provide_callback_query(
347344
case _:
348345
return None
349346

350-
@provide(scope=Scope.REQUEST)
351-
def provide_fsm_context(
352-
self,
353-
middleware_data: AiogramMiddlewareData,
354-
) -> FSMContext:
355-
return cast(FSMContext, middleware_data["state"])
356-
357347
@provide(scope=Scope.REQUEST)
358348
def provide_stars_purchase_payment_gateway(
359349
self,
@@ -437,7 +427,9 @@ class ApplicationProvider(Provider):
437427
)
438428
provide_cancel_game = provide(CancelGame, scope=Scope.REQUEST)
439429
provide_make_move_in_game = provide(MakeMoveInGame, scope=Scope.REQUEST)
440-
provide_make_ai_move_in_game = provide(MakeAiMoveInGame, scope=Scope.REQUEST)
430+
provide_make_ai_move_in_game = provide(
431+
MakeAiMoveInGame, scope=Scope.REQUEST,
432+
)
441433
provide_view_game = provide(ViewGame, scope=Scope.REQUEST)
442434

443435
provide_accept_invitation_to_game = provide(

0 commit comments

Comments
 (0)