Limit task execution concurrency based on task param

:wave: I’m learning about temporal. I’m building a fresh system. There are virtual agents (bots that imitate human behavior) and agents execute tasks (workflows). However, a particular agent shall execute only 1 task at a moment (the agent cannot execute tasks in parallel).

Example:
each agent has access to a different mobile device.
task 1: check for new DM messages (has result object);
task 2: check for new posts (has result object);
task 1 and task 2 cannot run simultaneously for a particular agent because something will break.
Then I have a manager type of workflow - e.g. purpose is to ensure surveillance of some social media group. So this workflow just issues the tasks for agents, waits for a result, puts it into database, and then continues as new 5 min later.

This is essentially a binary semaphore type of requirement. If the agent is free → task (workflow) can run; if the agent is busy → task (workflow) cannot run.

I see that one way would be to instantiate tasks (workflows) with task_queue parameter equal to agent_id. Then have 1 temporal worker for each agent_id.

But then if I was to have a few worker machines, then it’d seem I’d have to worry about distributing the workers myself somehow? For example, if I were to have 3 machines and 15 agents, then I’d have to make some custom script to start 5 different workers on each one? I feel like I’m losing some part of the distributed nature of Temporal. What if on one machine there are agents that are often busy but on other machine, there are agents that are often free, then I’m wasting resources (which isn’t a particularly hazardous outcome in my case but still)

So what’s the best way, the path of least resistance?

Don’t think about workers and machines when designing your business logic. Think of workflows and activities. Workflows are unique by a user-assigned WorkflowId. So, in your case, you want to have a workflow instance per virtual agent. You want to assign a unique agent ID to each such instance.

1 Like

So I may have an AgentExecutor workflow. It’d have id equal to agent_id, which would ensure there is only 1 such agent executor per system launched.

However, how would I make such workflow poll the task queue and execute pending tasks one by one?

For example, a task (workflow) that the agent executes would be “check new posts on a server with ID = something”. However, it’s not really a “self-existing” type of workflow because the manager/coordinator has to request this task. The manager (e.g. Discord Server Surveillance Manager workflow) runs every 5 min: issues a task for an agent to check new posts, retrieves the result, and puts it into the database.

So in such a case, how would the manager workflow issue the task? Under typical circumstances, it’d be using simple execute_child_workflow.

Don’t think about task queue polling :). A workflow can invoke an activity to execute every 5 minutes. The activity is going to perform the needed operations.

Also, for polling, various optimizations are covered in this topic.

1 Like