app.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import os
  2. import ujson
  3. import asyncpg
  4. from random import randint
  5. from multiprocessing import cpu_count
  6. from blacksheep.server import Application
  7. from blacksheep import Response, Header, Content
  8. from jinja2 import Template
  9. json_dumps = ujson.dumps
  10. async def configure_db(app):
  11. global db_pool
  12. db_pool = await asyncpg.create_pool(
  13. user=os.getenv('PGUSER', 'benchmarkdbuser'),
  14. password=os.getenv('PGPASS', 'benchmarkdbpass'),
  15. database='hello_world',
  16. host='tfb-database',
  17. port=5432
  18. )
  19. def load_fortunes_template():
  20. path = os.path.join('templates', 'fortune.html')
  21. with open(path, 'r') as template_file:
  22. template_text = template_file.read()
  23. return Template(template_text)
  24. db_pool = None
  25. fortune_template = load_fortunes_template()
  26. app = Application()
  27. app.on_start += configure_db
  28. def get_num_queries(request):
  29. try:
  30. value = request.query.get('queries')
  31. if value is None:
  32. return 1
  33. query_count = int(value[0])
  34. except (KeyError, IndexError, ValueError):
  35. return 1
  36. if query_count < 1:
  37. return 1
  38. if query_count > 500:
  39. return 500
  40. return query_count
  41. @app.route('/json')
  42. async def json_test(request):
  43. """Test type 1: JSON Serialization"""
  44. return Response(200, content=Content(b'application/json; charset=utf-8',
  45. json_dumps({'message': 'Hello, world!'}).encode('utf-8')))
  46. @app.route('/db')
  47. async def single_db_query_test(request):
  48. """Test type 2: Single Database Query"""
  49. row_id = randint(1, 10000)
  50. connection = await db_pool.acquire()
  51. try:
  52. number = await connection.fetchval('SELECT "randomnumber", "id" FROM "world" WHERE id = $1', row_id)
  53. world = {'id': row_id, 'randomNumber': number}
  54. finally:
  55. await db_pool.release(connection)
  56. return Response(200, content=Content(b'application/json; charset=utf-8',
  57. json_dumps(world).encode('utf-8')))
  58. @app.route('/queries')
  59. async def multiple_db_queries_test(request):
  60. """Test type 3: Multiple Database Queries"""
  61. num_queries = get_num_queries(request)
  62. row_ids = [randint(1, 10000) for _ in range(num_queries)]
  63. worlds = []
  64. connection = await db_pool.acquire()
  65. try:
  66. statement = await connection.prepare('SELECT "randomnumber", "id" FROM "world" WHERE id = $1')
  67. for row_id in row_ids:
  68. number = await statement.fetchval(row_id)
  69. worlds.append({'id': row_id, 'randomNumber': number})
  70. finally:
  71. await db_pool.release(connection)
  72. return Response(200, content=Content(b'application/json; charset=utf-8',
  73. json_dumps(worlds).encode('utf-8')))
  74. @app.route('/fortunes')
  75. async def fortunes_test(request):
  76. """Test type 4: Fortunes"""
  77. connection = await db_pool.acquire()
  78. try:
  79. fortunes = await connection.fetch('SELECT * FROM Fortune')
  80. finally:
  81. await db_pool.release(connection)
  82. fortunes.append([0, 'Additional fortune added at request time.'])
  83. fortunes.sort(key=lambda x: x[1])
  84. return Response(200, [
  85. Header(b'Cache-Control', b'no-cache')
  86. ], content=Content(b'text/html; charset=utf-8', fortune_template.render(fortunes=fortunes).encode('utf8')))
  87. @app.route('/updates')
  88. async def db_updates_test(request):
  89. """Test type 5: Database Updates"""
  90. num_queries = get_num_queries(request)
  91. updates = [(randint(1, 10000), randint(1, 10000)) for _ in range(num_queries)]
  92. worlds = [{'id': row_id, 'randomNumber': number} for row_id, number in updates]
  93. connection = await db_pool.acquire()
  94. try:
  95. statement = await connection.prepare('SELECT "randomnumber", "id" FROM "world" WHERE id = $1')
  96. for row_id, _ in updates:
  97. await statement.fetchval(row_id)
  98. await connection.executemany('UPDATE "world" SET "randomnumber"=$1 WHERE id=$2', updates)
  99. finally:
  100. await db_pool.release(connection)
  101. return Response(200, content=Content(b'application/json',
  102. json_dumps(worlds).encode('utf-8')))
  103. @app.route('/plaintext')
  104. async def plaintext_test(request):
  105. """Test type 6: Plaintext"""
  106. return Response(200, content=Content(b'text/plain', b'Hello, World!'))