def poll_task(server_config, href): """Wait for a task and its children to complete. Yield response bodies. Poll the task at ``href``, waiting for the task to complete. When a response is received indicating that the task is complete, yield that response body and recursively poll each child task. :param server_config: A :class:`pulp_smash.config.ServerConfig` object. :param href: The path to a task you'd like to monitor recursively. :returns: An generator yielding response bodies. :raises pulp_smash.exceptions.TaskTimedOutError: If a task takes too long to complete. """ poll_limit = 24 # 24 * 5s == 120s poll_counter = 0 while True: response = requests.get(urljoin(server_config.base_url, href), **server_config.get_requests_kwargs()) response.raise_for_status() attrs = response.json() if attrs['state'] in _TASK_END_STATES: yield attrs for spawned_task in attrs['spawned_tasks']: yield poll_task(server_config, spawned_task['_href']) break poll_counter += 1 if poll_counter > poll_limit: raise exceptions.TaskTimedOutError( 'Task {} is ongoing after {} polls.'.format(href, poll_limit)) # This approach is dumb, in that we don't account for time spent # waiting for the Pulp server to respond to us. sleep(5)
def poll_task(cfg, href, pulp_host=None): """Wait for a task and its children to complete. Yield response bodies. Poll the task at ``href``, waiting for the task to complete. When a response is received indicating that the task is complete, yield that response body and recursively poll each child task. :param cfg: A :class:`pulp_smash.config.PulpSmashConfig` object. :param href: The path to a task you'd like to monitor recursively. :param pulp_host: The host to poll. If ``None``, a host will automatically be selected by :class:`Client`. :returns: An generator yielding response bodies. :raises pulp_smash.exceptions.TaskTimedOutError: If a task takes too long to complete. """ # Read the timeout in seconds from the cfg, and divide by the sleep_time # to see how many times we query Pulp. # An example: Assuming timeout = 1800s, and sleep_time = 0.3s # 1800s/0.3s = 6000 if cfg.pulp_version < Version("3"): sleep_time = 2 else: sleep_time = 0.3 poll_limit = int(cfg.timeout / sleep_time) poll_counter = 0 json_client = Client(cfg, json_handler, pulp_host=pulp_host) logger.debug("Polling task %s with poll_limit %s", href, poll_limit) while True: task = json_client.get(href) if cfg.pulp_version < Version("3"): task_end_states = _TASK_END_STATES else: task_end_states = _P3_TASK_END_STATES if task["state"] in task_end_states: # This task has completed. Yield its final state, then recursively # iterate through children and yield their final states. yield task if "spawned_tasks" in task: for spawned_task in task["spawned_tasks"]: key = ( "_href" if cfg.pulp_version < Version("3") else "pulp_href" ) for descendant_tsk in poll_task( cfg, spawned_task[key], pulp_host ): yield descendant_tsk break poll_counter += 1 if poll_counter > poll_limit: raise exceptions.TaskTimedOutError( "Task {} is ongoing after {} polls.".format(href, poll_limit) ) logger.debug( "Polling %s progress %s/%s", href, poll_counter, poll_limit ) sleep(sleep_time)
def poll_task(server_config, href, pulp_system=None): """Wait for a task and its children to complete. Yield response bodies. Poll the task at ``href``, waiting for the task to complete. When a response is received indicating that the task is complete, yield that response body and recursively poll each child task. :param server_config: A :class:`pulp_smash.config.PulpSmashConfig` object. :param href: The path to a task you'd like to monitor recursively. :param pulp_system: The system from where to pool the task. If ``None`` is provided then the first system found with api role will be used. :returns: An generator yielding response bodies. :raises pulp_smash.exceptions.TaskTimedOutError: If a task takes too long to complete. """ if not pulp_system: pulp_system = server_config.get_systems('api')[0] # 360 * 5s == 1800s == 30m # NOTE: The timeout counter is synchronous. We query Pulp, then count down, # then query pulp, then count down, etc. This is… dumb. poll_limit = 360 poll_counter = 0 while True: response = requests.get( urljoin(server_config.get_base_url(pulp_system), href), **server_config.get_requests_kwargs(pulp_system)) response.raise_for_status() attrs = response.json() if server_config.pulp_version < Version('3'): task_end_states = _TASK_END_STATES else: task_end_states = _P3_TASK_END_STATES if attrs['state'] in task_end_states: # This task has completed. Yield its final state, then iterate # through each of its children and yield their final states. yield attrs for href_ in (task['_href'] for task in attrs['spawned_tasks']): for final_task_state in poll_task(server_config, href_): yield final_task_state break poll_counter += 1 if poll_counter > poll_limit: raise exceptions.TaskTimedOutError( 'Task {} is ongoing after {} polls.'.format(href, poll_limit)) sleep(5)
def poll_task(cfg, href, pulp_host=None): """Wait for a task and its children to complete. Yield response bodies. Poll the task at ``href``, waiting for the task to complete. When a response is received indicating that the task is complete, yield that response body and recursively poll each child task. :param cfg: A :class:`pulp_smash.config.PulpSmashConfig` object. :param href: The path to a task you'd like to monitor recursively. :param pulp_host: The host to poll. If ``None``, a host will automatically be selected by :class:`Client`. :returns: An generator yielding response bodies. :raises pulp_smash.exceptions.TaskTimedOutError: If a task takes too long to complete. """ # 900 * 2s == 1800s == 30m # NOTE: The timeout counter is synchronous. We query Pulp, then count down, # then query pulp, then count down, etc. This is… dumb. poll_limit = 900 poll_counter = 0 json_client = Client(cfg, json_handler, pulp_host=pulp_host) while True: task = json_client.get(href) if cfg.pulp_version < Version('3'): task_end_states = _TASK_END_STATES else: task_end_states = _P3_TASK_END_STATES if task['state'] in task_end_states: # This task has completed. Yield its final state, then recursively # iterate through children and yield their final states. yield task for spawned_task in task['spawned_tasks']: for descendant_tsk in poll_task(cfg, spawned_task['_href'], pulp_host): yield descendant_tsk break poll_counter += 1 if poll_counter > poll_limit: raise exceptions.TaskTimedOutError( 'Task {} is ongoing after {} polls.'.format(href, poll_limit) ) sleep(2)
def poll_task(server_config, href): """Wait for a task and its children to complete. Yield response bodies. Poll the task at ``href``, waiting for the task to complete. When a response is received indicating that the task is complete, yield that response body and recursively poll each child task. :param server_config: A :class:`pulp_smash.config.ServerConfig` object. :param href: The path to a task you'd like to monitor recursively. :returns: An generator yielding response bodies. :raises pulp_smash.exceptions.TaskTimedOutError: If a task takes too long to complete. """ # 360 * 5s == 1800s == 30m # NOTE: The timeout counter is synchronous. We query Pulp, then count down, # then query pulp, then count down, etc. This is… dumb. poll_limit = 360 poll_counter = 0 while True: response = requests.get(urljoin(server_config.base_url, href), **server_config.get_requests_kwargs()) response.raise_for_status() attrs = response.json() if attrs['state'] in _TASK_END_STATES: # This task has completed. Yield its final state, then iterate # through each of its children and yield their final states. yield attrs for href in (task['_href'] for task in attrs['spawned_tasks']): for final_task_state in poll_task(server_config, href): yield final_task_state break poll_counter += 1 if poll_counter > poll_limit: raise exceptions.TaskTimedOutError( 'Task {} is ongoing after {} polls.'.format(href, poll_limit)) sleep(5)