Skip to content

Commit 57c298a

Browse files
committed
feat: update app structure and replace ujson5 with orjson
1 parent 8898959 commit 57c298a

13 files changed

+290
-194
lines changed
7.51 KB
Binary file not shown.
8.43 KB
Binary file not shown.

frameworks/Python/litestar/app-socketify-asgi.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,43 @@
77
from socketify import ASGI
88

99

10-
app = Litestar()
11-
1210
@get("/json")
1311
async def json_serialization():
14-
return orjson.dumps({"message": "Hello, world!"})
12+
return orjson.dumps({"message": "Hello, world!"})
13+
1514

1615
@get("/plaintext", media_type=MediaType.TEXT)
1716
async def plaintext():
18-
return b"Hello, world!"
17+
return b"Hello, world!"
1918

2019

21-
_is_travis = os.environ.get('TRAVIS') == 'true'
20+
app = Litestar(
21+
route_handlers=[
22+
json_serialization,
23+
plaintext,
24+
]
25+
)
26+
27+
_is_travis = os.environ.get("TRAVIS") == "true"
2228

2329
workers = int(multiprocessing.cpu_count())
2430
if _is_travis:
25-
workers = 2
31+
workers = 2
32+
2633

2734
def run_app():
28-
ASGI(app).listen(8080, lambda config: logging.info(f"Listening on port http://localhost:{config.port} now\n")).run()
35+
ASGI(app).listen(8080, lambda config: logging.info(f"Listening on port http://localhost:{config.port} now\n")).run()
2936

3037

3138
def create_fork():
32-
n = os.fork()
33-
# n greater than 0 means parent process
34-
if not n > 0:
35-
run_app()
39+
n = os.fork()
40+
# n greater than 0 means parent process
41+
if not n > 0:
42+
run_app()
3643

3744

3845
# fork limiting the cpu count - 1
3946
for i in range(1, workers):
40-
create_fork()
47+
create_fork()
4148

42-
run_app() # run app on the main process too :)
49+
run_app() # run app on the main process too :)

frameworks/Python/litestar/app.py

Lines changed: 83 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,136 @@
11
import multiprocessing
2+
import os
23
from contextlib import asynccontextmanager
34
from pathlib import Path
5+
from random import randint, sample
6+
from typing import Any
47

58
import asyncpg
6-
import os
7-
89
import orjson
9-
from litestar import Litestar, Request, get, MediaType
10-
11-
from random import randint, sample
12-
10+
from litestar import Litestar, MediaType, Request, get
1311
from litestar.contrib.jinja import JinjaTemplateEngine
1412
from litestar.response import Template
1513
from litestar.template import TemplateConfig
1614

1715
READ_ROW_SQL = 'SELECT "id", "randomnumber" FROM "world" WHERE id = $1'
1816
WRITE_ROW_SQL = 'UPDATE "world" SET "randomnumber"=$1 WHERE id=$2'
1917
ADDITIONAL_ROW = [0, "Additional fortune added at request time."]
20-
MAX_POOL_SIZE = 1000//multiprocessing.cpu_count()
18+
MAX_POOL_SIZE = 1000 // multiprocessing.cpu_count()
2119
MIN_POOL_SIZE = max(int(MAX_POOL_SIZE / 2), 1)
2220

2321

2422
def get_num_queries(queries):
25-
try:
26-
query_count = int(queries)
27-
except (ValueError, TypeError):
28-
return 1
23+
try:
24+
query_count = int(queries)
25+
except (ValueError, TypeError):
26+
return 1
2927

30-
if query_count < 1:
31-
return 1
32-
if query_count > 500:
33-
return 500
34-
return query_count
28+
if query_count < 1:
29+
return 1
30+
if query_count > 500:
31+
return 500
32+
return query_count
3533

3634

3735
connection_pool = None
3836

3937

40-
4138
async def setup_database():
42-
return await asyncpg.create_pool(
43-
user=os.getenv("PGUSER", "benchmarkdbuser"),
44-
password=os.getenv("PGPASS", "benchmarkdbpass"),
45-
database="hello_world",
46-
host="tfb-database",
47-
port=5432,
48-
min_size=MIN_POOL_SIZE,
49-
max_size=MAX_POOL_SIZE,
50-
)
39+
return await asyncpg.create_pool(
40+
user=os.getenv("PGUSER", "benchmarkdbuser"),
41+
password=os.getenv("PGPASS", "benchmarkdbpass"),
42+
database="hello_world",
43+
host="tfb-database",
44+
port=5432,
45+
min_size=MIN_POOL_SIZE,
46+
max_size=MAX_POOL_SIZE,
47+
)
5148

5249

5350
@asynccontextmanager
5451
async def lifespan(app: Litestar):
55-
# Set up the database connection pool
56-
app.state.connection_pool = await setup_database()
57-
yield
58-
# Close the database connection pool
59-
await app.state.connection_pool.close()
60-
61-
62-
app = Litestar(lifespan=[lifespan], template_config=TemplateConfig(
63-
directory=Path("templates"),
64-
engine=JinjaTemplateEngine,
65-
),)
52+
# Set up the database connection pool
53+
app.state.connection_pool = await setup_database()
54+
yield
55+
# Close the database connection pool
56+
await app.state.connection_pool.close()
6657

6758

6859
@get("/json")
69-
async def json_serialization():
70-
return orjson.dumps({"message": "Hello, world!"})
60+
async def json_serialization() -> bytes:
61+
return orjson.dumps({"message": "Hello, world!"})
7162

7263

7364
@get("/db")
74-
async def single_database_query():
75-
row_id = randint(1, 10000)
76-
async with app.state.connection_pool.acquire() as connection:
77-
number = await connection.fetchval(READ_ROW_SQL, row_id)
65+
async def single_database_query() -> bytes:
66+
row_id = randint(1, 10000)
67+
async with app.state.connection_pool.acquire() as connection:
68+
number = await connection.fetchval(READ_ROW_SQL, row_id)
7869

79-
return orjson.dumps({"id": row_id, "randomNumber": number})
70+
return orjson.dumps({"id": row_id, "randomNumber": number})
8071

8172

8273
@get("/queries")
83-
async def multiple_database_queries(queries = None):
84-
num_queries = get_num_queries(queries)
85-
row_ids = sample(range(1, 10000), num_queries)
86-
worlds = []
74+
async def multiple_database_queries(queries: Any = None) -> bytes:
75+
num_queries = get_num_queries(queries)
76+
row_ids = sample(range(1, 10000), num_queries)
77+
worlds = []
8778

88-
async with app.state.connection_pool.acquire() as connection:
89-
statement = await connection.prepare(READ_ROW_SQL)
90-
for row_id in row_ids:
91-
number = await statement.fetchval(row_id)
92-
worlds.append({"id": row_id, "randomNumber": number})
79+
async with app.state.connection_pool.acquire() as connection:
80+
statement = await connection.prepare(READ_ROW_SQL)
81+
for row_id in row_ids:
82+
number = await statement.fetchval(row_id)
83+
worlds.append({"id": row_id, "randomNumber": number})
9384

94-
return orjson.dumps(worlds)
85+
return orjson.dumps(worlds)
9586

9687

9788
@get("/fortunes")
98-
async def fortunes(request: Request):
99-
async with app.state.connection_pool.acquire() as connection:
100-
fortunes = await connection.fetch("SELECT * FROM Fortune")
89+
async def fortunes(request: Request) -> Template:
90+
async with app.state.connection_pool.acquire() as connection:
91+
fortunes = await connection.fetch("SELECT * FROM Fortune")
10192

102-
fortunes.append(ADDITIONAL_ROW)
103-
fortunes.sort(key=lambda row: row[1])
104-
return Template("fortune.html", context={"fortunes": fortunes, "request": request})
93+
fortunes.append(ADDITIONAL_ROW)
94+
fortunes.sort(key=lambda row: row[1])
95+
return Template("fortune.html", context={"fortunes": fortunes, "request": request})
10596

10697

10798
@get("/updates")
108-
async def database_updates(queries = None):
109-
num_queries = get_num_queries(queries)
110-
# To avoid deadlock
111-
ids = sorted(sample(range(1, 10000 + 1), num_queries))
112-
numbers = sorted(sample(range(1, 10000), num_queries))
113-
updates = list(zip(ids, numbers))
99+
async def database_updates(queries: Any = None) -> bytes:
100+
num_queries = get_num_queries(queries)
101+
# To avoid deadlock
102+
ids = sorted(sample(range(1, 10000 + 1), num_queries))
103+
numbers = sorted(sample(range(1, 10000), num_queries))
104+
updates = list(zip(ids, numbers, strict=False))
114105

115-
worlds = [
116-
{"id": row_id, "randomNumber": number} for row_id, number in updates
117-
]
106+
worlds = [{"id": row_id, "randomNumber": number} for row_id, number in updates]
118107

119-
async with app.state.connection_pool.acquire() as connection:
120-
statement = await connection.prepare(READ_ROW_SQL)
121-
for row_id, _ in updates:
122-
await statement.fetchval(row_id)
123-
await connection.executemany(WRITE_ROW_SQL, updates)
108+
async with app.state.connection_pool.acquire() as connection:
109+
statement = await connection.prepare(READ_ROW_SQL)
110+
for row_id, _ in updates:
111+
await statement.fetchval(row_id)
112+
await connection.executemany(WRITE_ROW_SQL, updates)
124113

125-
return orjson.dumps(worlds)
114+
return orjson.dumps(worlds)
126115

127116

128117
@get("/plaintext", media_type=MediaType.TEXT)
129-
async def plaintext():
130-
return b"Hello, world!"
118+
async def plaintext() -> bytes:
119+
return b"Hello, world!"
120+
121+
122+
app = Litestar(
123+
lifespan=[lifespan],
124+
template_config=TemplateConfig(
125+
directory=Path("templates"),
126+
engine=JinjaTemplateEngine,
127+
),
128+
route_handlers=[
129+
json_serialization,
130+
single_database_query,
131+
multiple_database_queries,
132+
fortunes,
133+
database_updates,
134+
plaintext,
135+
],
136+
)

0 commit comments

Comments
 (0)