Repository: pulp/pulpcore

Issue:
As a user, I can see the status (idle, working) of my workers
Author: @dralley (dalley)


Redmine Issue: 9183, https://pulp.plan.io/issues/9183

---

It would be helpful if the worker API (and status API) should show the task currently executing on that worker, and/or state information such as "idle" / "working" for each worker.

It may also be a good idea for the status API to list the number of tasks currently queued up.

This would re-enable some of the functionality provided by the "rq info" and "qpid-stat" tools in the past.





Discussion:

Resolving patch:
diff --git a/pulpcore/app/models/task.py b/pulpcore/app/models/task.py
--- a/pulpcore/app/models/task.py
+++ b/pulpcore/app/models/task.py
@@ -89,6 +89,16 @@ class Worker(BaseModel):
     name = models.TextField(db_index=True, unique=True)
     last_heartbeat = models.DateTimeField(auto_now=True)
 
+    @property
+    def current_task(self):
+        """
+        The task this worker is currently executing, if any.
+
+        Returns:
+            Task: The currently executing task
+        """
+        return self.tasks.filter(state="running").first()
+
     @property
     def online(self):
         """
diff --git a/pulpcore/app/serializers/task.py b/pulpcore/app/serializers/task.py
--- a/pulpcore/app/serializers/task.py
+++ b/pulpcore/app/serializers/task.py
@@ -192,10 +192,15 @@ class WorkerSerializer(ModelSerializer):
     last_heartbeat = serializers.DateTimeField(
         help_text=_("Timestamp of the last time the worker talked to the service."), read_only=True
     )
-    # disable "created" because we don't care about it
-    created = None
+    current_task = RelatedField(
+        help_text=_(
+            "The task this worker is currently executing, or empty if the worker is not "
+            "currently assigned to a task."
+        ),
+        read_only=True,
+        view_name="tasks-detail",
+    )
 
     class Meta:
         model = models.Worker
-        _base_fields = tuple(set(ModelSerializer.Meta.fields) - set(["created"]))
-        fields = _base_fields + ("name", "last_heartbeat")
+        fields = ModelSerializer.Meta.fields + ("name", "last_heartbeat", "current_task")


Test patch:
diff --git a/pulpcore/tests/functional/api/test_workers.py b/pulpcore/tests/functional/api/test_workers.py
--- a/pulpcore/tests/functional/api/test_workers.py
+++ b/pulpcore/tests/functional/api/test_workers.py
@@ -10,18 +10,12 @@
 from pulpcore.tests.functional.utils import set_up_module as setUpModule  # noqa:F401
 from pulpcore.tests.functional.utils import skip_if
 
-_DYNAMIC_WORKER_ATTRS = ("last_heartbeat",)
+_DYNAMIC_WORKER_ATTRS = ("last_heartbeat", "current_task")
 """Worker attributes that are dynamically set by Pulp, not set by a user."""
 
 
 class WorkersTestCase(unittest.TestCase):
-    """Test actions over workers.
-
-    This test targets the following issues:
-
-    * `Pulp #3143 <https://pulp.plan.io/issues/3143>`_
-    * `Pulp Smash #945 <https://github.com/pulp/pulp-smash/issues/945>`_
-    """
+    """Test actions over workers."""
 
     @classmethod
     def setUpClass(cls):
@@ -38,6 +32,8 @@ def test_01_read_all_workers(self):
         workers = self.client.get(WORKER_PATH)["results"]
         for worker in workers:
             for key, val in worker.items():
+                if key in _DYNAMIC_WORKER_ATTRS:
+                    continue
                 with self.subTest(key=key):
                     self.assertIsNotNone(val)
         self.worker.update(choice(workers))