Skip to content

Commit 1e9c4d2

Browse files
authored
Adjust the unit startup mode
1 parent 87315e2 commit 1e9c4d2

File tree

5 files changed

+39
-50
lines changed

5 files changed

+39
-50
lines changed

frameworks/Python/blacksheep/app.py

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,27 @@
33
import asyncpg
44
import random
55
import asyncio
6-
from operator import itemgetter
76
import blacksheep as bs
87
import jinja2
98
import msgspec
109
from pathlib import Path
10+
try:
11+
import uvloop
12+
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
13+
except Exception:
14+
...
1115

1216
READ_ROW_SQL = 'SELECT "id", "randomnumber" FROM "world" WHERE id = $1'
1317
WRITE_ROW_SQL = 'UPDATE "world" SET "randomnumber"=$1 WHERE id=$2'
1418
ADDITIONAL_ROW = [0, "Additional fortune added at request time."]
15-
MAX_POOL_SIZE = 1000 // multiprocessing.cpu_count()
16-
MIN_POOL_SIZE = max(int(MAX_POOL_SIZE / 2), 1)
19+
MAX_CONNECTIONS = 1900
20+
CORE_COUNT = multiprocessing.cpu_count()
21+
WORKER_PROCESSES = CORE_COUNT
22+
MAX_POOL_SIZE = max(1, MAX_CONNECTIONS // WORKER_PROCESSES)
23+
MIN_POOL_SIZE = max(1, MAX_POOL_SIZE // 2)
1724
db_pool = None
1825
key = itemgetter(1)
1926

20-
try:
21-
import uvloop
22-
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
23-
except Exception:
24-
...
25-
2627
async def setup_db(app):
2728
global db_pool
2829
db_pool = await asyncpg.create_pool(
@@ -33,8 +34,17 @@ async def setup_db(app):
3334
port=5432,
3435
min_size=MIN_POOL_SIZE,
3536
max_size=MAX_POOL_SIZE,
37+
command_timeout=5,
38+
max_inactive_connection_lifetime=60,
39+
server_settings={'jit': 'off'},
3640
)
3741

42+
async def shutdown_db(app):
43+
"""Close asyncpg connection pool for the current process."""
44+
global db_pool
45+
if db_pool is not None:
46+
await db_pool.close()
47+
db_pool = None
3848

3949
def load_fortunes_template():
4050
with Path("templates/fortune.html").open("r") as f:
@@ -45,7 +55,7 @@ def load_fortunes_template():
4555

4656
app = bs.Application()
4757
app.on_start += setup_db
48-
58+
app.on_stop += shutdown_db
4959

5060
def get_num_queries(request):
5161
try:
@@ -55,14 +65,9 @@ def get_num_queries(request):
5565
query_count = int(value[0])
5666
except (KeyError, IndexError, ValueError):
5767
return 1
58-
if query_count < 1:
59-
return 1
60-
if query_count > 500:
61-
return 500
62-
return query_count
68+
return min(max(query_count, 1), 500)
6369

6470
ENCODER = msgspec.json.Encoder()
65-
DECODER = msgspec.json.Decoder()
6671
JSON_CONTENT_TYPE = b"application/json"
6772
def jsonify(
6873
data,
@@ -122,26 +127,22 @@ async def fortunes_test(request):
122127
fortunes = await db_conn.fetch("SELECT * FROM Fortune")
123128

124129
fortunes.append(ADDITIONAL_ROW)
125-
fortunes.sort(key = key)
130+
fortunes.sort(key=lambda row: row[1])
126131
data = fortune_template.render(fortunes=fortunes)
127132
return bs.html(data)
128133

129134

130135
@bs.get('/updates')
131136
async def db_updates_test(request):
132137
num_queries = get_num_queries(request)
133-
ids = sorted(random.sample(range(1, 10000 + 1), num_queries))
134-
numbers = sorted(random.sample(range(1, 10000), num_queries))
135-
updates = list(zip(ids, numbers))
136-
137-
# worlds = [ {"id": row_id, "randomNumber": number} for row_id, number in updates ]
138+
updates = [(row_id, random.randint(1, 10000)) for row_id in random.sample(range(1, 10000), num_queries)]
138139
worlds = [Result(id=row_id, randomNumber=number) for row_id, number in updates]
140+
# worlds = [ {"id": row_id, "randomNumber": number} for row_id, number in updates ]
139141
async with db_pool.acquire() as db_conn:
140142
statement = await db_conn.prepare(READ_ROW_SQL)
141143
for row_id, _ in updates:
142144
await statement.fetchval(row_id)
143145
await db_conn.executemany(WRITE_ROW_SQL, updates)
144-
145146
return jsonify(worlds)
146147

147148

frameworks/Python/blacksheep/blacksheep-nginx-unit.dockerfile

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ WORKDIR /blacksheep
44

55
COPY ./ /blacksheep
66

7-
RUN pip3 install -U pip
8-
RUN pip3 install Cython==3.0.12
9-
RUN pip3 install -r /blacksheep/requirements.txt
10-
RUN pip3 install -r /blacksheep/requirements-uvicorn.txt
11-
12-
RUN chmod +x start-unit.sh
7+
RUN pip3 install -U pip -q
8+
RUN pip3 install Cython==3.0.12 -q
9+
RUN pip3 install -r /blacksheep/requirements.txt -q
10+
RUN pip3 install -r /blacksheep/requirements-uvicorn.txt -q
1311

1412
ENV PGSSLMODE=disable
13+
RUN CORE_COUNT=$(nproc) && \
14+
MAX_PROCESSES=$((CORE_COUNT)) && \
15+
sed -i "s|\"processes\": [0-9]*|\"processes\": $MAX_PROCESSES|g" /blacksheep/unit-config.json
16+
17+
RUN unitd && \
18+
curl -X PUT --data-binary @/blacksheep/unit-config.json --unix-socket \
19+
/var/run/control.unit.sock http://localhost/config
1520

21+
ENTRYPOINT []
1622
EXPOSE 8080
17-
CMD ["./start-unit.sh"]
23+
CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
asyncpg==0.30.0
22
Jinja2==3.1.6
3-
blacksheep==2.1.0
3+
blacksheep==2.2.0
44
msgspec==0.19.0

frameworks/Python/blacksheep/start-unit.sh

Lines changed: 0 additions & 18 deletions
This file was deleted.

frameworks/Python/blacksheep/unit-config.template.json renamed to frameworks/Python/blacksheep/unit-config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"protocol": "asgi",
1313
"module": "app",
1414
"callable": "app",
15-
"processes": {{NPROC}}
15+
"processes": 56
1616
}
1717
},
1818
"access_log": "/dev/null"

0 commit comments

Comments
 (0)