Comment 5 for bug 1259910

Revision history for this message
Max Lobur (max-lobur) wrote :

About terminology - when you're saying task you mean not a task acquired inside conductor by

with task_manager.acquire(context, node_id, shared=False) as task:

right? It's different thing, a REST API Task, which is simply the lock in db. If so then I assume we don't need to call the rpcapi to get it, we may reserve it directly from the API.

2. R: "power_state_task" for changing power state and then "deploy_task" for deployments? Maybe to have some generic "task" for all such purposes? Because there is also could be mixed race codition - the first client requests change_node_power_state and the second requests undeploy.

In that way we will have two node locks in DB, "reservation" and "task". So could we join them into one? F.e. currently we're putting CONF.host to node's "reservation" field, but what if we put the task_uuid there:

def post(...):
        try:
            reservation_key = reserve_node(node_id) # This generates uuid, tries to put it to the node.reservation, and then returns.
       except Exception:
            raise Exception("Node A already reserved for another task")

      ... check if target is a valid state ...

     rpcapi.change_node_power_state(pecan.request.context, rpc_node, target, reservation_key) # giving reservation key to the conductor.

Then in conductor:

    with task_manager.acquire(context, node_id, reservation_key=reservation_key, shared=False) as task:
# The task_manager opens the node using the received reservation_key (acquire will compare node.reservation uuid with given key), does the job, and unlocks the node after it's done.

reservation_key will be optional parameter of task_manager.acquire, if not supplied then it will be generated on the fly.