PageRenderTime 28ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/permalink_server.py

https://github.com/sagemath/sagecell
Python | 91 lines | 65 code | 16 blank | 10 comment | 12 complexity | 79b5c847287b656f9d7bc1cfbb261d3b MD5 | raw file
  1. """
  2. Permalink web server
  3. This Tornado server provides a permalink service with a convenient
  4. post/get api for storing and retrieving code.
  5. """
  6. import os
  7. import signal
  8. import psutil
  9. import tornado.httpserver
  10. import tornado.ioloop
  11. import tornado.web
  12. import permalink
  13. from log import permalink_logger as logger
  14. PERMALINK_DB = "sqlalchemy"
  15. PERMALINK_URI = "sqlite:///permalinks.db"
  16. PERMALINK_PID_FILE = "permalink.pid"
  17. class PermalinkServer(tornado.web.Application):
  18. def __init__(self):
  19. handlers_list = [
  20. (r"/", permalink.PermalinkHandler),
  21. (r"/permalink", permalink.PermalinkHandler),
  22. ]
  23. db = __import__('db_' + PERMALINK_DB)
  24. self.db = db.DB(PERMALINK_URI)
  25. #self.ioloop = ioloop.IOLoop.instance()
  26. # to check for blocking when debugging, uncomment the following
  27. # and set the argument to the blocking timeout in seconds
  28. #self.ioloop.set_blocking_log_threshold(.5)
  29. super(PermalinkServer, self).__init__(handlers_list)
  30. if __name__ == "__main__":
  31. import argparse
  32. parser = argparse.ArgumentParser(
  33. description='Launch a permalink database web server',
  34. formatter_class=argparse.ArgumentDefaultsHelpFormatter)
  35. parser.add_argument('-p', '--port', type=int, default=8080,
  36. help='port to launch the server')
  37. args = parser.parse_args()
  38. from lockfile.pidlockfile import PIDLockFile
  39. pidfile_path = PERMALINK_PID_FILE
  40. pidlock = PIDLockFile(pidfile_path)
  41. if pidlock.is_locked():
  42. old_pid = pidlock.read_pid()
  43. if os.getpid() != old_pid:
  44. try:
  45. old = psutil.Process(old_pid)
  46. if os.path.basename(__file__) in old.cmdline():
  47. try:
  48. old.terminate()
  49. try:
  50. old.wait(10)
  51. except psutil.TimeoutExpired:
  52. old.kill()
  53. except psutil.AccessDenied:
  54. pass
  55. except psutil.NoSuchProcess:
  56. pass
  57. pidlock.break_lock()
  58. pidlock.acquire(timeout=10)
  59. app = PermalinkServer()
  60. app.listen(port=args.port, xheaders=True)
  61. def handler(signum, frame):
  62. logger.info("Received %s, shutting down...", signum)
  63. ioloop = tornado.ioloop.IOLoop.current()
  64. ioloop.add_callback_from_signal(ioloop.stop)
  65. signal.signal(signal.SIGHUP, handler)
  66. signal.signal(signal.SIGINT, handler)
  67. signal.signal(signal.SIGTERM, handler)
  68. try:
  69. from systemd.daemon import notify
  70. notify('READY=1\nMAINPID={}'.format(os.getpid()), True)
  71. except ImportError:
  72. pass
  73. tornado.ioloop.IOLoop.current().start()
  74. pidlock.release()