From f87b405e8ce72544084472079939e987a9ad9bec Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Wed, 17 Dec 2008 13:18:35 +0000
Subject: [PATCH] Add job queue size limit

A job queue with too many jobs can increase memory usage and/or make
the master daemon slow. The current limit is just an arbitrary number.
A "soft" limit for automatic job archival is prepared.

Reviewed-by: iustinp
---
 lib/cli.py       |  3 +++
 lib/constants.py |  2 ++
 lib/errors.py    |  8 ++++++++
 lib/jqueue.py    | 12 ++++++++++++
 4 files changed, 25 insertions(+)

diff --git a/lib/cli.py b/lib/cli.py
index 737c4016e..dea707801 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -687,6 +687,9 @@ def FormatError(err):
   elif isinstance(err, errors.JobQueueDrainError):
     obuf.write("Failure: the job queue is marked for drain and doesn't"
                " accept new requests\n")
+  elif isinstance(err, errors.JobQueueFull):
+    obuf.write("Failure: the job queue is full and doesn't accept new"
+               " job submissions until old jobs are archived\n")
   elif isinstance(err, errors.GenericError):
     obuf.write("Unhandled Ganeti error: %s" % msg)
   elif isinstance(err, luxi.NoMasterError):
diff --git a/lib/constants.py b/lib/constants.py
index a5748c900..7dfa2ac41 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -366,6 +366,8 @@ JOB_QUEUE_VERSION_FILE = QUEUE_DIR + "/version"
 JOB_QUEUE_SERIAL_FILE = QUEUE_DIR + "/serial"
 JOB_QUEUE_ARCHIVE_DIR = QUEUE_DIR + "/archive"
 JOB_QUEUE_DRAIN_FILE = QUEUE_DIR + "/drain"
+JOB_QUEUE_SIZE_HARD_LIMIT = 5000
+JOB_QUEUE_SIZE_SOFT_LIMIT = JOB_QUEUE_SIZE_HARD_LIMIT * 0.8
 
 JOB_ID_TEMPLATE = r"\d+"
 
diff --git a/lib/errors.py b/lib/errors.py
index 4f3d86d5a..b54a1493a 100644
--- a/lib/errors.py
+++ b/lib/errors.py
@@ -253,6 +253,14 @@ class JobQueueDrainError(JobQueueError):
   """
 
 
+class JobQueueFull(JobQueueError):
+  """Job queue full error.
+
+  Raised when job queue size reached its hard limit.
+
+  """
+
+
 # errors should be added above
 
 
diff --git a/lib/jqueue.py b/lib/jqueue.py
index 38b13b73b..373447607 100644
--- a/lib/jqueue.py
+++ b/lib/jqueue.py
@@ -941,6 +941,18 @@ class JobQueue(object):
     """
     if self._IsQueueMarkedDrain():
       raise errors.JobQueueDrainError()
+
+    # Check job queue size
+    size = len(self._ListJobFiles())
+    if size >= constants.JOB_QUEUE_SIZE_SOFT_LIMIT:
+      # TODO: Autoarchive jobs. Make sure it's not done on every job
+      # submission, though.
+      #size = ...
+      pass
+
+    if size >= constants.JOB_QUEUE_SIZE_HARD_LIMIT:
+      raise errors.JobQueueFull()
+
     # Get job identifier
     job_id = self._NewSerialUnlocked()
     job = _QueuedJob(self, job_id, ops)
-- 
GitLab