Skip to content

Chapter 7 · TaskSet and Nested Tasks ​

Chapter goals: Master the TaskSet class for hierarchical task organization, learn to use interrupt() to exit sub-task sets, and understand on_start / on_stop lifecycle methods.

7.1 Why TaskSet Exists ​

When user behavior models grow complex (e.g., "login → browse products → add to cart → checkout"), stacking all @task methods in one HttpUser class becomes unmaintainable. TaskSet lets you group tasks by business scenario:

python
from locust import HttpUser, TaskSet, task, between

class BrowsingBehavior(TaskSet):
    """Simulate a user browsing products"""

    @task(5)
    def view_products(self):
        self.client.get("/api/products")

    @task(3)
    def view_product_detail(self):
        self.client.get("/api/products/1")

    @task(1)
    def stop_browsing(self):
        # Exit browsing mode
        self.interrupt()


class ShoppingUser(HttpUser):
    wait_time = between(1, 3)
    host = "https://shop.example.com"
    tasks = {BrowsingBehavior: 10}  # Weight 10

HttpUser references one or more TaskSet classes via the tasks attribute. When a TaskSet is selected, its tasks loop until interrupt() is called to return to the parent.

7.2 Nested TaskSet ​

TaskSets can nest multiple levels deep, building complex user journey models:

python
class LoginTask(TaskSet):
    @task
    def login(self):
        resp = self.client.post("/api/login", json={
            "username": "test_user",
            "password": "secret"
        })
        if resp.status_code == 200:
            # Login succeeded — enter the shopping flow
            self.interrupt()  # Return to parent


class ShoppingTask(TaskSet):
    tasks = {
        BrowseProducts: 5,
        AddToCart: 3,
        Checkout: 1
    }

    @task
    def stay_here(self):
        pass  # Fallback task to keep the current level alive


class EcommerceUser(HttpUser):
    wait_time = between(1, 3)
    host = "https://shop.example.com"

    tasks = [LoginTask]

Each TaskSet level has its own weight system. interrupt(reschedule=True) can re-trigger task selection immediately after returning.

7.3 interrupt() Usage ​

interrupt() is the key method for returning from a child TaskSet to its parent. Without it, the agent stays in the current TaskSet forever.

python
class SessionTimeout(TaskSet):
    @task
    def check_session(self):
        resp = self.client.get("/api/session/check")
        if resp.json().get("expired"):
            self.interrupt(reschedule=True)  # Session expired → return to parent to re-login

    @task
    def do_work(self):
        self.client.get("/api/work")
python
# interrupt() parameter guide
self.interrupt()                    # Exit and wait for next scheduled task
self.interrupt(reschedule=True)     # Exit and immediately re-select a task

Forgetting interrupt()

The most common error: forgetting to set an exit condition in a child TaskSet, causing all virtual users to get permanently stuck at that level. Ensure every child TaskSet has at least one path that triggers interrupt().

7.4 on_start and on_stop ​

Lifecycle hooks at the TaskSet level:

python
class BrowsingBehavior(TaskSet):
    def on_start(self):
        """Run once when this TaskSet is entered"""
        self.client.get("/api/products")

    def on_stop(self):
        """Run once when this TaskSet is exited via interrupt()"""
        self.client.get("/api/logout")

    @task
    def view_product(self):
        self.client.get("/api/products/1")

7.5 Chapter Summary ​

  • TaskSet groups related tasks into named behavior blocks;
  • tasks = {TaskSetClass: weight} on HttpUser selects which behavior to run;
  • interrupt() exits the current TaskSet and returns to the parent;
  • interrupt(reschedule=True) re-selects immediately;
  • on_start() / on_stop() run at TaskSet entry/exit for setup/teardown.

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. What happens if you forget to call interrupt() in a TaskSet?

2. What does interrupt(reschedule=True) do differently from interrupt()?

3. How do you reference a TaskSet from an HttpUser?

4. When does on_stop() in a TaskSet execute?

🛠️ Hands-On Exercises ​

  1. Build a LoginTask → BrowsingTask → CheckoutTask nested hierarchy; verify each phase runs in order.
  2. Add on_start() and on_stop() to a TaskSet; print logs to confirm they fire at entry and exit.
  3. Deliberately omit interrupt() from one task in a child TaskSet; observe users getting stuck and fix it.

Proceed to Chapter 8: Event Hooks and Custom Statistics.