Skip to content

Commit 4bd1f46

Browse files
authored
Merge pull request #16 from emptybutton/dev
2 parents 2641be6 + 67f854f commit 4bd1f46

File tree

101 files changed

+2047
-362
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+2047
-362
lines changed

.github/workflows/cd.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ jobs:
1717
echo "bot_token: ${{ secrets.BOT_TOKEN }}" > deploy/prod/ttt/secrets.yaml
1818
echo "payments_token: ${{ secrets.PAYMENTS_TOKEN }}" >> deploy/prod/ttt/secrets.yaml
1919
echo "gemini_api_key: ${{ secrets.GEMINI_API_KEY }}" >> deploy/prod/ttt/secrets.yaml
20+
echo "sentry_dsn: ${{ secrets.SENTRY_DSN }}" >> deploy/prod/ttt/secrets.yaml
2021
2122
- name: deploy
2223
run: bash ./deploy/prod/deploy.sh
@@ -29,3 +30,5 @@ jobs:
2930
NATS_TOKEN: ${{ secrets.NATS_TOKEN }}
3031

3132
GEMINI_URL: ${{ secrets.GEMINI_URL }}
33+
34+
GRAFANA_ADMIN_PASSWORD: ${{ secrets.GRAFANA_ADMIN_PASSWORD }}

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
echo "bot_token: ${{ secrets.BOT_TOKEN }}" > deploy/dev/ttt/secrets.yaml
1414
echo "payments_token: ${{ secrets.PAYMENTS_TOKEN }}" >> deploy/dev/ttt/secrets.yaml
1515
echo "gemini_api_key: ${{ secrets.GEMINI_API_KEY }}" >> deploy/dev/ttt/secrets.yaml
16+
echo "sentry_dsn: ${{ secrets.SENTRY_DSN }}" >> deploy/dev/ttt/secrets.yaml
1617
1718
- name: ruff
1819
run: docker compose -f deploy/dev/docker-compose.yaml run ttt ruff check src tests
@@ -27,6 +28,7 @@ jobs:
2728
echo "bot_token: ${{ secrets.BOT_TOKEN }}" > deploy/dev/ttt/secrets.yaml
2829
echo "payments_token: ${{ secrets.PAYMENTS_TOKEN }}" >> deploy/dev/ttt/secrets.yaml
2930
echo "gemini_api_key: ${{ secrets.GEMINI_API_KEY }}" >> deploy/dev/ttt/secrets.yaml
31+
echo "sentry_dsn: ${{ secrets.SENTRY_DSN }}" >> deploy/dev/ttt/secrets.yaml
3032
3133
- name: mypy
3234
run: docker compose -f deploy/dev/docker-compose.yaml run ttt mypy src tests
@@ -41,6 +43,7 @@ jobs:
4143
echo "bot_token: ${{ secrets.BOT_TOKEN }}" > deploy/dev/ttt/secrets.yaml
4244
echo "payments_token: ${{ secrets.PAYMENTS_TOKEN }}" >> deploy/dev/ttt/secrets.yaml
4345
echo "gemini_api_key: ${{ secrets.GEMINI_API_KEY }}" >> deploy/dev/ttt/secrets.yaml
46+
echo "sentry_dsn: ${{ secrets.SENTRY_DSN }}" >> deploy/dev/ttt/secrets.yaml
4447
4548
- name: pytest
4649
run: docker compose -f deploy/dev/docker-compose.yaml run ttt pytest tests --cov --cov-report=xml

deploy/dev/docker-compose.yaml

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ name: ttt
22

33
services:
44
ttt:
5+
image: ttt:dev
56
build:
67
context: ../../
78
dockerfile: deploy/dev/ttt/Dockerfile
@@ -26,7 +27,7 @@ services:
2627
TTT_POSTGRES_POOL_TIMEOUT_SECONDS: 30
2728
TTT_POSTGRES_POOL_RECYCLE_SECONDS: 1800
2829
TTT_POSTGRES_POOL_PRE_PING: false
29-
TTT_POSTGRES_ECHO: true
30+
TTT_POSTGRES_ECHO: false
3031

3132
TTT_REDIS_URL: redis://redis:6379/0
3233
TTT_REDIS_POOL_SIZE: 16
@@ -54,7 +55,7 @@ services:
5455
POSTGRES_PASSWORD: root
5556
healthcheck:
5657
test: pg_isready -d root -U root
57-
start_period: 1m
58+
start_period: 2m
5859
start_interval: 1s
5960
interval: 5s
6061

@@ -97,10 +98,14 @@ services:
9798
command: ["bash", "/mnt/add_streams.sh"]
9899

99100
volumes:
100-
backend-data: null
101-
postgres-data: null
102-
redis-data: null
103-
nats-data: null
101+
backend-data:
102+
name: "ttt-dev-postgres-backend-data"
103+
postgres-data:
104+
name: "ttt-dev-postgres-postgres-data"
105+
redis-data:
106+
name: "ttt-dev-postgres-redis-data"
107+
nats-data:
108+
name: "ttt-dev-postgres-nats-data"
104109

105110
secrets:
106111
secrets:

deploy/prod/.env.template

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ POSTGRES_REPLICA_PASSWORD=replica
66
NATS_TOKEN=nats
77

88
GEMINI_URL=https://my-gemini.vercel.app
9+
10+
GRAFANA_ADMIN_PASSWORD=grafana

deploy/prod/alloy/config.alloy

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// This component is responsible for disovering new containers within the docker environment
2+
discovery.docker "getting_started" {
3+
host = "unix:///var/run/docker.sock"
4+
refresh_interval = "5s"
5+
}
6+
7+
// This component is responsible for relabeling the discovered containers
8+
discovery.relabel "getting_started" {
9+
targets = []
10+
11+
rule {
12+
source_labels = ["__meta_docker_container_name"]
13+
regex = "/(.*)"
14+
target_label = "container"
15+
}
16+
}
17+
18+
// This component is responsible for collecting logs from the discovered containers
19+
loki.source.docker "getting_started" {
20+
host = "unix:///var/run/docker.sock"
21+
targets = discovery.docker.getting_started.targets
22+
forward_to = [loki.process.getting_started.receiver]
23+
relabel_rules = discovery.relabel.getting_started.rules
24+
refresh_interval = "5s"
25+
}
26+
27+
// This component is responsible for processing the logs (In this case adding static labels)
28+
loki.process "getting_started" {
29+
stage.static_labels {
30+
values = {
31+
env = "production",
32+
}
33+
}
34+
forward_to = [loki.write.getting_started.receiver]
35+
}
36+
37+
// This component is responsible for writing the logs to Loki
38+
loki.write "getting_started" {
39+
endpoint {
40+
url = "http://loki:3100/loki/api/v1/push"
41+
}
42+
}
43+
44+
// Enables the ability to view logs in the Alloy UI in realtime
45+
livedebugging {
46+
enabled = true
47+
}

deploy/prod/docker-compose.yaml

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ name: ttt
22

33
services:
44
ttt:
5+
image: ttt:prod
56
build:
67
context: ../../
78
dockerfile: deploy/prod/ttt/Dockerfile
@@ -26,7 +27,7 @@ services:
2627
TTT_POSTGRES_POOL_TIMEOUT_SECONDS: 45
2728
TTT_POSTGRES_POOL_RECYCLE_SECONDS: 1800
2829
TTT_POSTGRES_POOL_PRE_PING: false
29-
TTT_POSTGRES_ECHO: true
30+
TTT_POSTGRES_ECHO: false
3031

3132
TTT_REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0
3233
TTT_REDIS_POOL_SIZE: 16
@@ -86,7 +87,7 @@ services:
8687
mem_limit: 30mb
8788
healthcheck:
8889
test: pg_isready -d ttt -U ttt
89-
start_period: 1m
90+
start_period: 2m
9091
start_interval: 1s
9192
interval: 5s
9293

@@ -116,7 +117,7 @@ services:
116117
mem_limit: 30mb
117118
healthcheck:
118119
test: pg_isready -d ttt -U ttt
119-
start_period: 1m
120+
start_period: 2m
120121
start_interval: 1s
121122
interval: 5s
122123

@@ -154,6 +155,57 @@ services:
154155
entrypoint: [""]
155156
command: ["bash", "/mnt/add_streams.sh"]
156157

158+
alloy:
159+
image: grafana/alloy:v1.10.0
160+
container_name: ttt-alloy
161+
volumes:
162+
- ./alloy/config.alloy:/etc/alloy/config.alloy
163+
- /var/run/docker.sock:/var/run/docker.sock
164+
networks:
165+
- loki
166+
command: run --server.http.listen-addr=0.0.0.0:12345 --storage.path=/var/lib/alloy/data /etc/alloy/config.alloy
167+
depends_on:
168+
- loki
169+
170+
loki:
171+
image: grafana/loki:3.4.5
172+
container_name: ttt-loki
173+
environment:
174+
TZ: ${SYSTEM_TIMEZONE:-Europe/Moscow}
175+
volumes:
176+
- loki-data:/loki
177+
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml
178+
networks:
179+
- loki
180+
command: -config.file=/etc/loki/local-config.yaml
181+
182+
grafana:
183+
image: grafana/grafana:12.0.2-ubuntu
184+
container_name: ttt-grafana
185+
environment:
186+
- GF_PATHS_PROVISIONING=/etc/grafana/provisioning
187+
- GF_FEATURE_TOGGLES_ENABLE=grafanaManagedRecordingRules
188+
189+
- GF_AUTH_ANONYMOUS_ENABLED=false
190+
- GF_AUTH_BASIC_ENABLED=true
191+
192+
- GF_SECURITY_FORCE_PASSWORD_CHANGE=true
193+
- GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION=false
194+
- GF_SECURITY_ADMIN_USER=admin
195+
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
196+
- GF_SECURITY_MIN_PASSWORD_LENGTH=4
197+
198+
- GF_USERS_ALLOW_SIGN_UP=false
199+
200+
- TZ=${SYSTEM_TIMEZONE:-Europe/Moscow}
201+
ports:
202+
- 3000:3000
203+
volumes:
204+
- grafana-data:/var/lib/grafana
205+
- ./grafana/provisioning/datasources:/etc/grafana/provisioning/datasources
206+
networks:
207+
- loki
208+
157209
volumes:
158210
postgres-replica1-data:
159211
name: "ttt-prod-postgres-replica1-data"
@@ -163,11 +215,16 @@ volumes:
163215
name: "ttt-prod-redis-data"
164216
nats-data:
165217
name: "ttt-prod-nats-data"
218+
loki-data:
219+
name: "ttt-prod-loki-data"
220+
grafana-data:
221+
name: "ttt-prod-grafana-data"
166222

167223
networks:
168224
postgres: null
169225
redis: null
170226
nats: null
227+
loki: null
171228

172229
secrets:
173230
secrets:
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: 1
2+
datasources:
3+
- name: Loki
4+
type: loki
5+
access: proxy
6+
orgId: 1
7+
url: http://loki:3100
8+
basicAuth: false
9+
isDefault: true
10+
version: 1
11+
editable: true

deploy/prod/loki/loki-config.yaml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
auth_enabled: false
2+
3+
server:
4+
http_listen_port: 3100
5+
grpc_listen_port: 9096
6+
log_level: info
7+
grpc_server_max_concurrent_streams: 1000
8+
9+
common:
10+
instance_addr: 127.0.0.1
11+
path_prefix: /tmp/loki
12+
storage:
13+
filesystem:
14+
chunks_directory: /tmp/loki/chunks
15+
rules_directory: /tmp/loki/rules
16+
replication_factor: 1
17+
ring:
18+
kvstore:
19+
store: inmemory
20+
21+
query_range:
22+
results_cache:
23+
cache:
24+
embedded_cache:
25+
enabled: true
26+
max_size_mb: 100
27+
28+
limits_config:
29+
metric_aggregation_enabled: true
30+
allow_structured_metadata: true
31+
volume_enabled: true
32+
retention_period: 24h # 24h
33+
34+
schema_config:
35+
configs:
36+
- from: 2020-10-24
37+
store: tsdb
38+
object_store: filesystem
39+
schema: v13
40+
index:
41+
prefix: index_
42+
period: 24h
43+
44+
pattern_ingester:
45+
enabled: true
46+
metric_aggregation:
47+
loki_address: localhost:3100
48+
49+
ruler:
50+
enable_alertmanager_discovery: true
51+
enable_api: true
52+
53+
54+
frontend:
55+
encoding: protobuf
56+
57+
58+
compactor:
59+
working_directory: /tmp/loki/retention
60+
delete_request_store: filesystem
61+
retention_enabled: true

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ dependencies = [
2222
"aiogram==3.20.0.post0",
2323
"nats-py[nkeys]==2.10.0",
2424
"openai==1.97.0",
25+
"structlog==25.4.0",
26+
"structlog-sentry==2.2.1",
2527
]
2628

2729
[dependency-groups]
@@ -32,7 +34,7 @@ dev = [
3234
"pytest-cov==6.1.1",
3335
"pytest-asyncio==1.0.0",
3436
"dirty-equals==0.9.0",
35-
"watchfiles==1.1.0",
37+
"better-exceptions==0.3.3",
3638
]
3739

3840
[project.urls]

src/ttt/application/game/common/ports/game_ai_gateway.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@
77
class GameAiGateway(ABC):
88
@abstractmethod
99
async def next_move_cell_number_int(
10-
self, game: Game, ai_id: UUID, /,
10+
self,
11+
game: Game,
12+
ai_id: UUID,
13+
/,
1114
) -> int | None: ...

0 commit comments

Comments
 (0)