app.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import os
  2. import sys
  3. from functools import partial
  4. from operator import attrgetter
  5. from random import randint
  6. import json
  7. import cherrypy
  8. from sqlalchemy.ext.declarative import declarative_base
  9. from sqlalchemy import Column
  10. from sqlalchemy.types import String, Integer
  11. try:
  12. from cgi import escape as html_escape
  13. except:
  14. from html import escape as html_escape
  15. Base = declarative_base()
  16. if sys.version_info[0] == 3:
  17. xrange = range
  18. def getQueryNum(queryString):
  19. try:
  20. int(queryString)
  21. return int(queryString)
  22. except ValueError:
  23. return 1
  24. class Fortune(Base):
  25. __tablename__ = "fortune"
  26. id = Column(Integer, primary_key=True)
  27. message = Column(String)
  28. def serialize(self):
  29. return {'id': self.id, 'message': self.message}
  30. class World(Base):
  31. __tablename__ = "world"
  32. id = Column(Integer, primary_key=True)
  33. randomNumber = Column(Integer)
  34. def serialize(self):
  35. return {'id': self.id, 'randomNumber': self.randomNumber}
  36. class CherryPyBenchmark(object):
  37. @cherrypy.expose
  38. @cherrypy.tools.json_out()
  39. def json(self):
  40. cherrypy.response.headers["Content-Type"] = "application/json"
  41. json_message = {"message": "Hello, world!"}
  42. return json_message
  43. @cherrypy.expose
  44. def plaintext(self):
  45. cherrypy.response.headers["Content-Type"] = "text/plain"
  46. return "Hello, world!"
  47. @cherrypy.expose
  48. @cherrypy.tools.json_out()
  49. def db(self):
  50. cherrypy.response.headers["Content-Type"] = "application/json"
  51. wid = randint(1, 10000)
  52. world = cherrypy.request.db.query(World).get(wid).serialize()
  53. return world
  54. @cherrypy.expose
  55. @cherrypy.tools.json_out()
  56. def queries(self, queries=1):
  57. num_queries = getQueryNum(queries)
  58. if num_queries < 1:
  59. num_queries = 1
  60. if num_queries > 500:
  61. num_queries = 500
  62. rp = partial(randint, 1, 10000)
  63. get = cherrypy.request.db.query(World).get
  64. worlds = [get(rp()).serialize() for _ in xrange(num_queries)]
  65. return worlds
  66. @cherrypy.expose
  67. @cherrypy.tools.json_out()
  68. def updates(self, queries=1):
  69. cherrypy.response.headers["Content-Type"] = "application/json"
  70. num_queries = getQueryNum(queries)
  71. if num_queries < 1:
  72. num_queries = 1
  73. if num_queries > 500:
  74. num_queries = 500
  75. worlds = []
  76. rp = partial(randint, 1, 10000)
  77. ids = [rp() for _ in xrange(num_queries)]
  78. ids.sort() # To avoid deadlock
  79. for id in ids:
  80. world = cherrypy.request.db.query(World).get(id)
  81. world.randomNumber = rp()
  82. worlds.append(world.serialize())
  83. cherrypy.request.db.commit()
  84. return worlds
  85. @cherrypy.expose
  86. def fortunes(self):
  87. _fortunes = cherrypy.request.db.query(Fortune).all()
  88. _fortunes.append( Fortune(id=0, message="Additional fortune added at request time.") )
  89. _fortunes.sort(key=attrgetter("message"))
  90. html = "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>"
  91. for f in _fortunes:
  92. html += "<tr><td>" + str(f.id) + "</td><td>" + html_escape(f.message) + "</td></tr>"
  93. html += "</table></body></html>"
  94. return html
  95. if __name__ == "__main__":
  96. import logging
  97. import multiprocessing
  98. # Register the SQLAlchemy plugin
  99. from saplugin import SAEnginePlugin
  100. DBDRIVER = 'mysql'
  101. DBUSER = 'benchmarkdbuser'
  102. DBPSWD = 'benchmarkdbpass'
  103. DATABASE_URI = '%s://%s:%s@tfb-database:3306/hello_world?charset=utf8' % (
  104. DBDRIVER, DBUSER, DBPSWD)
  105. SAEnginePlugin(cherrypy.engine, DATABASE_URI).subscribe()
  106. _is_travis = os.environ.get('TRAVIS') == 'true'
  107. workers = int(multiprocessing.cpu_count())
  108. if _is_travis:
  109. workers = 3
  110. cherrypy._cpconfig.environments['staging']['log.screen'] = False
  111. logging.getLogger("cherrypy").propagate = False
  112. log_fmt = "%(asctime)s.%(msecs)03d [%(levelname)s] (%(name)s) %(message)s"
  113. logging.basicConfig(level=logging.CRITICAL, format=log_fmt, datefmt="%Y-%m-%d %H:%M:%S")
  114. cherrypy.config.update({
  115. 'tools.db.on': True,
  116. 'environment': 'production',
  117. 'log.screen': False,
  118. 'log.access_file': '',
  119. 'log.error_file': ''
  120. })
  121. # Register the SQLAlchemy tool
  122. from satool import SATool
  123. cherrypy.tools.db = SATool()
  124. cherrypy.server.socket_host = '0.0.0.0'
  125. cherrypy.server.socket_port = 8080
  126. cherrypy.server.thread_pool = workers
  127. cherrypy.quickstart(CherryPyBenchmark(), '', {
  128. '/': {
  129. 'tools.db.on': True,
  130. 'log.screen': False,
  131. 'log.access_file': '',
  132. 'log.error_file': ''
  133. }
  134. })