You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

145 lines
3.8 KiB

  1. # imports - standard imports
  2. import getpass
  3. import json
  4. import os
  5. default_config = {
  6. "restart_supervisor_on_update": False,
  7. "restart_systemd_on_update": False,
  8. "serve_default_site": True,
  9. "rebase_on_pull": False,
  10. "xhiveframework_user": getpass.getuser(),
  11. "shallow_clone": True,
  12. "background_workers": 1,
  13. "use_redis_auth": False,
  14. "live_reload": True,
  15. }
  16. DEFAULT_MAX_REQUESTS = 5000
  17. def setup_config(bench_path, additional_config=None):
  18. make_pid_folder(bench_path)
  19. bench_config = get_config(bench_path)
  20. bench_config.update(default_config)
  21. bench_config.update(get_gunicorn_workers())
  22. update_config_for_xhiveframework(bench_config, bench_path)
  23. if additional_config:
  24. bench_config.update(additional_config)
  25. put_config(bench_config, bench_path)
  26. def get_config(bench_path):
  27. return get_common_site_config(bench_path)
  28. def get_common_site_config(bench_path):
  29. config_path = get_config_path(bench_path)
  30. if not os.path.exists(config_path):
  31. return {}
  32. with open(config_path) as f:
  33. return json.load(f)
  34. def put_config(config, bench_path="."):
  35. config_path = get_config_path(bench_path)
  36. with open(config_path, "w") as f:
  37. return json.dump(config, f, indent=1, sort_keys=True)
  38. def update_config(new_config, bench_path="."):
  39. config = get_config(bench_path=bench_path)
  40. config.update(new_config)
  41. put_config(config, bench_path=bench_path)
  42. def get_config_path(bench_path):
  43. return os.path.join(bench_path, "sites", "common_site_config.json")
  44. def get_gunicorn_workers():
  45. """This function will return the maximum workers that can be started depending upon
  46. number of cpu's present on the machine"""
  47. import multiprocessing
  48. return {"gunicorn_workers": multiprocessing.cpu_count() * 2 + 1}
  49. def compute_max_requests_jitter(max_requests: int) -> int:
  50. return int(max_requests * 0.1)
  51. def get_default_max_requests(worker_count: int):
  52. """Get max requests and jitter config based on number of available workers."""
  53. if worker_count <= 1:
  54. # If there's only one worker then random restart can cause spikes in response times and
  55. # can be annoying. Hence not enabled by default.
  56. return 0
  57. return DEFAULT_MAX_REQUESTS
  58. def update_config_for_xhiveframework(config, bench_path):
  59. ports = make_ports(bench_path)
  60. for key in ("redis_cache", "redis_queue", "redis_socketio"):
  61. if key not in config:
  62. config[key] = f"redis://127.0.0.1:{ports[key]}"
  63. for key in ("webserver_port", "socketio_port", "file_watcher_port"):
  64. if key not in config:
  65. config[key] = ports[key]
  66. def make_ports(bench_path):
  67. from urllib.parse import urlparse
  68. benches_path = os.path.dirname(os.path.abspath(bench_path))
  69. default_ports = {
  70. "webserver_port": 8000,
  71. "socketio_port": 9000,
  72. "file_watcher_port": 6787,
  73. "redis_queue": 11000,
  74. "redis_socketio": 13000,
  75. "redis_cache": 13000,
  76. }
  77. # collect all existing ports
  78. existing_ports = {}
  79. for folder in os.listdir(benches_path):
  80. bench_path = os.path.join(benches_path, folder)
  81. if os.path.isdir(bench_path):
  82. bench_config = get_config(bench_path)
  83. for key in list(default_ports.keys()):
  84. value = bench_config.get(key)
  85. # extract port from redis url
  86. if value and (key in ("redis_cache", "redis_queue", "redis_socketio")):
  87. value = urlparse(value).port
  88. if value:
  89. existing_ports.setdefault(key, []).append(value)
  90. # new port value = max of existing port value + 1
  91. ports = {}
  92. for key, value in list(default_ports.items()):
  93. existing_value = existing_ports.get(key, [])
  94. if existing_value:
  95. value = max(existing_value) + 1
  96. ports[key] = value
  97. # Backward compatbility: always keep redis_cache and redis_socketio port same
  98. # Note: not required from v15
  99. ports["redis_socketio"] = ports["redis_cache"]
  100. return ports
  101. def make_pid_folder(bench_path):
  102. pids_path = os.path.join(bench_path, "config", "pids")
  103. if not os.path.exists(pids_path):
  104. os.makedirs(pids_path)