|
@@ -3,15 +3,13 @@ import os
|
|
|
|
|
|
from operator import itemgetter
|
|
|
from pathlib import Path
|
|
|
-from random import randint
|
|
|
+from random import randint, sample
|
|
|
from urllib.parse import parse_qs
|
|
|
|
|
|
import asyncpg
|
|
|
import jinja2
|
|
|
import orjson
|
|
|
|
|
|
-from granian.rsgi import Response
|
|
|
-
|
|
|
|
|
|
async def pg_setup():
|
|
|
global pool
|
|
@@ -28,9 +26,9 @@ SQL_SELECT = 'SELECT "randomnumber", "id" FROM "world" WHERE id = $1'
|
|
|
SQL_UPDATE = 'UPDATE "world" SET "randomnumber"=$1 WHERE id=$2'
|
|
|
ROW_ADD = [0, 'Additional fortune added at request time.']
|
|
|
|
|
|
-JSON_HEADERS = {'content-type': 'application/json'}
|
|
|
-HTML_HEADERS = {'content-type': 'text/html; charset=utf-8'}
|
|
|
-PLAINTEXT_HEADERS = {'content-type': 'text/plain; charset=utf-8'}
|
|
|
+JSON_HEADERS = [('content-type', 'application/json')]
|
|
|
+HTML_HEADERS = [('content-type', 'text/html; charset=utf-8')]
|
|
|
+PLAINTEXT_HEADERS = [('content-type', 'text/plain; charset=utf-8')]
|
|
|
|
|
|
pool = None
|
|
|
key = itemgetter(1)
|
|
@@ -56,74 +54,92 @@ def get_num_queries(scope):
|
|
|
|
|
|
|
|
|
async def route_json(scope, proto):
|
|
|
- return Response.bytes(json_dumps({'message': 'Hello, world!'}), 200, JSON_HEADERS)
|
|
|
+ proto.response_bytes(
|
|
|
+ 200,
|
|
|
+ JSON_HEADERS,
|
|
|
+ json_dumps({'message': 'Hello, world!'})
|
|
|
+ )
|
|
|
|
|
|
|
|
|
async def route_db(scope, proto):
|
|
|
row_id = randint(1, 10000)
|
|
|
- connection = await pool.acquire()
|
|
|
- try:
|
|
|
+ async with pool.acquire() as connection:
|
|
|
number = await connection.fetchval(SQL_SELECT, row_id)
|
|
|
- world = {'id': row_id, 'randomNumber': number}
|
|
|
- finally:
|
|
|
- await pool.release(connection)
|
|
|
|
|
|
- return Response.bytes(json_dumps(world), 200, JSON_HEADERS)
|
|
|
+ proto.response_bytes(
|
|
|
+ 200,
|
|
|
+ JSON_HEADERS,
|
|
|
+ json_dumps({'id': row_id, 'randomNumber': number})
|
|
|
+ )
|
|
|
|
|
|
|
|
|
async def route_queries(scope, proto):
|
|
|
num_queries = get_num_queries(scope)
|
|
|
- row_ids = [randint(1, 10000) for _ in range(num_queries)]
|
|
|
+ row_ids = sample(range(1, 10000), num_queries)
|
|
|
worlds = []
|
|
|
|
|
|
- connection = await pool.acquire()
|
|
|
- try:
|
|
|
+ async with pool.acquire() as connection:
|
|
|
statement = await connection.prepare(SQL_SELECT)
|
|
|
for row_id in row_ids:
|
|
|
number = await statement.fetchval(row_id)
|
|
|
worlds.append({'id': row_id, 'randomNumber': number})
|
|
|
- finally:
|
|
|
- await pool.release(connection)
|
|
|
|
|
|
- return Response.bytes(json_dumps(worlds), 200, JSON_HEADERS)
|
|
|
+ proto.response_bytes(
|
|
|
+ 200,
|
|
|
+ JSON_HEADERS,
|
|
|
+ json_dumps(worlds)
|
|
|
+ )
|
|
|
|
|
|
|
|
|
async def route_fortunes(scope, proto):
|
|
|
- connection = await pool.acquire()
|
|
|
- try:
|
|
|
+ async with pool.acquire() as connection:
|
|
|
fortunes = await connection.fetch('SELECT * FROM Fortune')
|
|
|
- finally:
|
|
|
- await pool.release(connection)
|
|
|
|
|
|
fortunes.append(ROW_ADD)
|
|
|
fortunes.sort(key=key)
|
|
|
content = template.render(fortunes=fortunes)
|
|
|
- return Response.str(content, 200, HTML_HEADERS)
|
|
|
+ proto.response_str(
|
|
|
+ 200,
|
|
|
+ HTML_HEADERS,
|
|
|
+ content
|
|
|
+ )
|
|
|
|
|
|
|
|
|
async def route_updates(scope, proto):
|
|
|
num_queries = get_num_queries(scope)
|
|
|
- updates = [(randint(1, 10000), randint(1, 10000)) for _ in range(num_queries)]
|
|
|
+ updates = list(zip(
|
|
|
+ sorted(sample(range(1, 10000), num_queries)),
|
|
|
+ sample(range(1, 10000), num_queries)
|
|
|
+ ))
|
|
|
worlds = [{'id': row_id, 'randomNumber': number} for row_id, number in updates]
|
|
|
|
|
|
- connection = await pool.acquire()
|
|
|
- try:
|
|
|
+ async with pool.acquire() as connection:
|
|
|
statement = await connection.prepare(SQL_SELECT)
|
|
|
for row_id, _ in updates:
|
|
|
await statement.fetchval(row_id)
|
|
|
await connection.executemany(SQL_UPDATE, updates)
|
|
|
- finally:
|
|
|
- await pool.release(connection)
|
|
|
|
|
|
- return Response.bytes(json_dumps(worlds), 200, JSON_HEADERS)
|
|
|
+ proto.response_bytes(
|
|
|
+ 200,
|
|
|
+ JSON_HEADERS,
|
|
|
+ json_dumps(worlds)
|
|
|
+ )
|
|
|
|
|
|
|
|
|
async def route_plaintext(scope, proto):
|
|
|
- return Response.bytes(b'Hello, world!', 200, PLAINTEXT_HEADERS)
|
|
|
+ proto.response_bytes(
|
|
|
+ 200,
|
|
|
+ PLAINTEXT_HEADERS,
|
|
|
+ b'Hello, world!'
|
|
|
+ )
|
|
|
|
|
|
|
|
|
async def handle_404(scope, proto):
|
|
|
- return Response.bytes(b'Not found', 404, PLAINTEXT_HEADERS)
|
|
|
+ proto.response_bytes(
|
|
|
+ 404,
|
|
|
+ PLAINTEXT_HEADERS,
|
|
|
+ b'Not found'
|
|
|
+ )
|
|
|
|
|
|
|
|
|
routes = {
|