Skip to content

Commit 201aa2d

Browse files
committed
feat: notify players about active payment (#4)
1 parent a6537b3 commit 201aa2d

18 files changed

+230
-82
lines changed

src/ttt/application/player/complete_stars_purshase.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,28 @@
33
from ttt.application.common.ports.clock import Clock
44
from ttt.application.common.ports.map import Map
55
from ttt.application.common.ports.transaction import Transaction
6+
from ttt.application.player.ports.paid_stars_purchase_payment_inbox import (
7+
PaidStarsPurchasePaymentInbox,
8+
)
69
from ttt.application.player.ports.player_views import PlayerViews
710
from ttt.application.player.ports.players import Players
8-
from ttt.application.player.ports.stars_purchase_payment_gateway import (
9-
StarsPurchasePaymentGateway,
10-
)
1111
from ttt.entities.finance.payment.payment import PaymentAlreadyCompletedError
1212
from ttt.entities.tools.tracking import Tracking
1313

1414

1515
@dataclass(frozen=True, unsafe_hash=False)
1616
class CompleteStarsPurshase:
1717
clock: Clock
18-
payment_gateway: StarsPurchasePaymentGateway
18+
inbox: PaidStarsPurchasePaymentInbox
1919
players: Players
2020
transaction: Transaction
2121
map_: Map
2222
player_views: PlayerViews
2323

2424
async def __call__(self) -> None:
25-
current_datetime = await self.clock.current_datetime()
25+
async for paid_payment in self.inbox.stream():
26+
current_datetime = await self.clock.current_datetime()
2627

27-
async for paid_payment in self.payment_gateway.paid_payment_stream():
2828
async with self.transaction:
2929
player = await self.players.player_with_id(
3030
paid_payment.location.player_id,

src/ttt/application/player/dto/__init__.py

Whitespace-only changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from dataclasses import dataclass
2+
from uuid import UUID
3+
4+
from ttt.entities.core.player.location import PlayerLocation
5+
from ttt.entities.finance.payment.success import PaymentSuccess
6+
7+
8+
@dataclass(frozen=True)
9+
class PaidStarsPurchasePayment:
10+
purshase_id: UUID
11+
location: PlayerLocation
12+
success: PaymentSuccess
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from abc import ABC, abstractmethod
2+
from collections.abc import AsyncIterable
3+
4+
from ttt.application.player.dto.common import PaidStarsPurchasePayment
5+
6+
7+
class PaidStarsPurchasePaymentInbox(ABC):
8+
@abstractmethod
9+
async def push(self, payment: PaidStarsPurchasePayment) -> None: ...
10+
11+
@abstractmethod
12+
def stream(self) -> AsyncIterable[PaidStarsPurchasePayment]:
13+
...

src/ttt/application/player/ports/player_views.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ async def render_non_exchangeable_rubles_for_stars_view(
8383
self, location: PlayerLocation, /,
8484
) -> None: ...
8585

86+
@abstractmethod
87+
async def render_stars_purchase_will_be_completed_view(
88+
self, location: PlayerLocation, /,
89+
) -> None: ...
90+
8691
@abstractmethod
8792
async def render_completed_stars_purshase_view(
8893
self, player: Player, purshase_id: UUID, location: PlayerLocation, /,

src/ttt/application/player/ports/stars_purchase_payment_gateway.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,9 @@
11
from abc import ABC, abstractmethod
22
from collections.abc import AsyncIterable
3-
from dataclasses import dataclass
4-
from uuid import UUID
53

4+
from ttt.application.player.dto.common import PaidStarsPurchasePayment
65
from ttt.entities.core.player.location import PlayerLocation
76
from ttt.entities.core.player.stars_purchase import StarsPurchase
8-
from ttt.entities.finance.payment.success import PaymentSuccess
9-
10-
11-
@dataclass(frozen=True)
12-
class PaidStarsPurchasePayment:
13-
purshase_id: UUID
14-
location: PlayerLocation
15-
success: PaymentSuccess
167

178

189
class StarsPurchasePaymentGateway(ABC):
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from dataclasses import dataclass
2+
3+
from ttt.application.player.ports.paid_stars_purchase_payment_inbox import (
4+
PaidStarsPurchasePaymentInbox,
5+
)
6+
from ttt.application.player.ports.player_views import PlayerViews
7+
from ttt.application.player.ports.stars_purchase_payment_gateway import (
8+
StarsPurchasePaymentGateway,
9+
)
10+
11+
12+
@dataclass(frozen=True, unsafe_hash=False)
13+
class StartStarsPurshaseCompletion:
14+
inbox: PaidStarsPurchasePaymentInbox
15+
payment_gateway: StarsPurchasePaymentGateway
16+
player_views: PlayerViews
17+
18+
async def __call__(self) -> None:
19+
async for paid_payment in self.payment_gateway.paid_payment_stream():
20+
await self.inbox.push(paid_payment)
21+
await (
22+
self.player_views
23+
.render_stars_purchase_will_be_completed_view(
24+
paid_payment.location,
25+
)
26+
)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from collections.abc import AsyncIterable
2+
from dataclasses import dataclass
3+
4+
from ttt.application.player.dto.common import PaidStarsPurchasePayment
5+
from ttt.application.player.ports.paid_stars_purchase_payment_inbox import (
6+
PaidStarsPurchasePaymentInbox,
7+
)
8+
from ttt.infrastructure.nats.paid_stars_purchase_payment_inbox import (
9+
InNatsPaidStarsPurchasePaymentInbox as OriginalInNatsPaidStarsPurchasePaymentInbox, # noqa: E501
10+
)
11+
12+
13+
@dataclass(frozen=True)
14+
class InNatsPaidStarsPurchasePaymentInbox(PaidStarsPurchasePaymentInbox):
15+
_inbox: OriginalInNatsPaidStarsPurchasePaymentInbox
16+
17+
async def push(self, payment: PaidStarsPurchasePayment) -> None:
18+
await self._inbox.push(payment)
19+
20+
async def stream(self) -> AsyncIterable[PaidStarsPurchasePayment]:
21+
async for payment in self._inbox:
22+
yield payment

src/ttt/infrastructure/buffer.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from asyncio import Event
2+
from collections import deque
3+
from collections.abc import AsyncIterator
4+
from dataclasses import dataclass, field
5+
6+
7+
@dataclass(frozen=True, unsafe_hash=False)
8+
class Buffer[ValueT]:
9+
_values: deque[ValueT] = field(default_factory=deque)
10+
_has_values: Event = field(default_factory=Event, init=False)
11+
12+
def __post_init__(self) -> None:
13+
if self._values:
14+
self._has_values.set()
15+
16+
def __len__(self) -> int:
17+
return len(self._values)
18+
19+
def add(self, value: ValueT) -> None:
20+
self._values.append(value)
21+
self._has_values.set()
22+
23+
async def stream(self) -> AsyncIterator[ValueT]:
24+
while True:
25+
await self._has_values.wait()
26+
yield self._values.popleft()
27+
28+
if not self._values:
29+
self._has_values.clear()

src/ttt/infrastructure/nats/paid_stars_purchase_payment_inbox.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
from nats.js import JetStreamContext
77
from pydantic import TypeAdapter
88

9-
from ttt.application.player.ports.stars_purchase_payment_gateway import (
10-
PaidStarsPurchasePayment,
11-
)
9+
from ttt.application.player.dto.common import PaidStarsPurchasePayment
1210
from ttt.infrastructure.nats.messages import at_least_once_messages
1311

1412

0 commit comments

Comments
 (0)