app.py 4.4 KB

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