-
-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add blacksheep in benchmarks and update benchmarks with latest versio…
…n of each library
- Loading branch information
Showing
15 changed files
with
447 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
FROM python:3.9-slim | ||
|
||
COPY . . | ||
RUN pip install -r requirements.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
version: '3' | ||
|
||
services: | ||
gateway: | ||
build: . | ||
container_name: gateway | ||
command: uvicorn gateway:app --host 0.0.0.0 --port 8000 --workers 8 --log-level warning | ||
ports: | ||
- "8000:8000" | ||
depends_on: | ||
- server | ||
- redis | ||
server: | ||
build: . | ||
container_name: server | ||
command: uvicorn server:app --host 0.0.0.0 --port 8011 --workers 8 --log-level warning | ||
ports: | ||
- "8011:8011" | ||
# cpus: '0.50' | ||
# mem_limit: 256m | ||
redis: | ||
image: eqalpha/keydb:latest | ||
container_name: redis | ||
ports: | ||
- "6379:6379" | ||
wrk-hello: | ||
image: skandyla/wrk | ||
command: -t 8 -c 64 -d 15s --latency http://gateway:8000/hello | ||
depends_on: | ||
- gateway | ||
wrk-order: | ||
image: skandyla/wrk | ||
command: -t 8 -c 64 -d 15s --latency http://gateway:8000/order | ||
depends_on: | ||
- gateway |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import logging | ||
from typing import Optional | ||
|
||
from blacksheep import Application, JSONContent | ||
from blacksheep import json as json_resp | ||
from blacksheep import text | ||
from blacksheep.client import ClientSession | ||
|
||
app = Application() | ||
get = app.router.get | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
try: | ||
import uvloop | ||
|
||
uvloop.install() | ||
except ImportError: | ||
logger.warning("Cannot use uvloop") | ||
|
||
session: Optional[ClientSession] = None | ||
|
||
|
||
@get("/hello") | ||
async def hello(): | ||
global session | ||
if session is None: | ||
session = ClientSession() | ||
|
||
resp = await session.get("http://server:8011/hello") | ||
txt = await resp.text() | ||
return text(txt) | ||
|
||
|
||
@get("/order") | ||
async def order(): | ||
global session | ||
if session is None: | ||
session = ClientSession() | ||
|
||
content = JSONContent( | ||
data={ | ||
"user_id": "1", | ||
"items": ["apple", "python"], | ||
} | ||
) | ||
resp = await session.post("http://server:8011/order", content=content) | ||
return json_resp(await resp.json()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
blacksheep | ||
uvicorn | ||
PyJWT | ||
aioredis | ||
uvloop | ||
msgpack | ||
redis |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import logging | ||
import uuid | ||
from dataclasses import dataclass | ||
from datetime import datetime | ||
from typing import List | ||
|
||
from blacksheep import Application, FromJSON, json, text | ||
from shared import Order, OrderResp, OrderStatus, async_save_order | ||
|
||
app = Application() | ||
get = app.router.get | ||
post = app.router.post | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
try: | ||
import uvloop | ||
|
||
uvloop.install() | ||
except ImportError: | ||
logger.warning("Cannot use uvloop") | ||
|
||
|
||
@get("/hello") | ||
async def hello(): | ||
return text("hello world") | ||
|
||
|
||
@get("/order") | ||
async def get_order(): | ||
saved_order = await async_save_order( | ||
Order( | ||
id=str(uuid.uuid4()), | ||
created_by="1", | ||
items=["apple", "python"], | ||
created_at=datetime.now().isoformat(), | ||
status=OrderStatus.INITIATED, | ||
) | ||
) | ||
|
||
resp = OrderResp( | ||
saved_order.id, | ||
saved_order.status, | ||
saved_order.items, | ||
) | ||
return json( | ||
{ | ||
"id": resp.order_id, | ||
"status": resp.status, | ||
"items": resp.items, | ||
} | ||
) | ||
|
||
|
||
@dataclass | ||
class OrderReq: | ||
user_id: str | ||
items: List[str] | ||
|
||
|
||
@post("/order") | ||
async def order(req: FromJSON[OrderReq]): | ||
body = req.value | ||
saved_order = await async_save_order( | ||
Order( | ||
id=str(uuid.uuid4()), | ||
created_by=body.user_id, | ||
items=body.items, | ||
created_at=datetime.now().isoformat(), | ||
status=OrderStatus.INITIATED, | ||
) | ||
) | ||
|
||
resp = OrderResp( | ||
saved_order.id, | ||
saved_order.status, | ||
saved_order.items, | ||
) | ||
return json( | ||
{ | ||
"id": resp.order_id, | ||
"status": resp.status, | ||
"items": resp.items, | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
from dataclasses import dataclass | ||
from datetime import datetime | ||
|
||
import aioredis | ||
import msgpack | ||
import redis | ||
|
||
|
||
@dataclass | ||
class Btype: | ||
def pack(self): | ||
return msgpack.packb(Btype.get_all_vars(self)) | ||
|
||
@classmethod | ||
def unpack(cls, d): | ||
return cls(**msgpack.unpackb(d, raw=False)) | ||
|
||
@staticmethod | ||
def get_all_vars(obj): | ||
values = vars(obj) | ||
for k, v in values.items(): | ||
if isinstance(v, Btype): | ||
values[k] = vars(v) | ||
return values | ||
|
||
|
||
class OrderStatus: | ||
INITIATED = 0 | ||
PACKING = 1 | ||
SHIPPED = 2 | ||
DELIVERED = 3 | ||
|
||
|
||
class Order(Btype): | ||
# cache | ||
orders = {} | ||
|
||
def __init__(self, id, items, created_by, created_at, status, updated_at=None): | ||
self.id = id | ||
self.items = items | ||
self.created_by = created_by | ||
self.created_at = created_at | ||
self.status = status | ||
self.updated_at = updated_at | ||
|
||
|
||
@dataclass | ||
class OrderResp(Btype): | ||
order_id: str | ||
status: int | ||
items: list | ||
|
||
|
||
@dataclass | ||
class CreateOrderReq(Btype): | ||
user_id: str | ||
items: list | ||
|
||
|
||
class SingletonMeta(type): | ||
_instance = None | ||
|
||
def __call__(self): | ||
if self._instance is None: | ||
self._instance = super().__call__() | ||
return self._instance | ||
|
||
|
||
class AsyncRedisClient(metaclass=SingletonMeta): | ||
def __init__(self): | ||
self.client = aioredis.from_url("redis://redis:6379/0") | ||
|
||
async def set(self, key, val): | ||
await self.client.set(key, val) | ||
|
||
async def get(self, key): | ||
return await self.client.get(key) | ||
|
||
|
||
async def async_save_order(order: Order) -> Order: | ||
order.updated_at = datetime.now().isoformat() | ||
r = AsyncRedisClient() | ||
await r.set(order.id, order.pack()) | ||
return order | ||
|
||
|
||
async def async_get_order(id: str) -> Order: | ||
r = AsyncRedisClient() | ||
return Order.unpack(await r.get(id)) | ||
|
||
|
||
class SingletonMeta(type): | ||
_instance = None | ||
|
||
def __call__(self): | ||
if self._instance is None: | ||
self._instance = super().__call__() | ||
return self._instance | ||
|
||
|
||
class RedisClient(metaclass=SingletonMeta): | ||
def __init__(self): | ||
self.host = "0.0.0.0" | ||
self.client = redis.StrictRedis().from_url("redis://redis:6379/0") | ||
|
||
def set(self, key, val): | ||
self.client.set(key, val) | ||
|
||
def get(self, key): | ||
return self.client.get(key) | ||
|
||
|
||
def save_order(order: Order) -> Order: | ||
order.updated_at = datetime.now().isoformat() | ||
r = RedisClient() | ||
r.set(order.id, order.pack()) | ||
return order | ||
|
||
|
||
def get_order(id: str) -> Order: | ||
r = RedisClient() | ||
return Order.unpack(r.get(id)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.