New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
play, block, task: New attribute forks #42528
Conversation
I would call this option forks, make it override the global forks option and make this configurable on a per-task, per-block, per-role and per-play option, see: #24037 |
This comment has been minimized.
This comment has been minimized.
…f CA There is a pull request and also a proposal for ansible be able to limit the number of concurrent executions for a single task: - ansible/proposals#129 - ansible/ansible#42528 The keyword is currently named max_concurrent, but might be renamed later on. If the keyword is present, but not supported by ansible, it will be simply ignored. Therefore there is no issue right now with adding in here early.
This comment has been minimized.
This comment has been minimized.
This looks like a really simple change for a feature that could be really useful. I have a few situations where this would make things a lot simpler. If the core devs don't have anything against it, how can we get them to discuss about the name of the option and get it merged? |
@kustodian simple to add, but not when dealing with implications:
And I'm sure I'm missing quite a few considerations, the list above is just from the top of my head. These, and more, have been brought up in adhoc and core IRC meetings discussing this topic (but possibly not this specific ticket) and we have not found good answers for most of those, we need to be able to answer all of the above before we consider adding it to the code base. |
@bcoca then it's best to just close this ticket with the explanation that it complicates a lot of things and because of that it will not be added into Ansible anytime in the near future. |
@kustodian we are still considering the feature, we just need to figure out how to deal with all the associated issues it entails. |
@bcoca here are answers for the items where I am able to provide answers for the open questions.
The minimum of global fork limit and inventory hosts defines how many workers are created. The current implementation of max_concurrent is done in StrategyBase._queue_task. It is only effective if max_concurrent is bigger than 0 and max_concurrent is smaller than the number of workers. If the current worker index (self._cur_worker) is greater or equal task.max_concurrent the index is set back to 0. This is the same mechanism that is used to switch back to worker 0 if the maximum number of workers has been reached.
Batches are created according to the number of hosts that need to be processed with limiting the number of hosts in a batch to serial count. These batches are processed one after the other. The inventory is restricted to the hosts that are part of the batch while processing the batch. As the number of hosts defined in the inventory will also limit the number of workers, max_concurrent will only have an effect if it is smaller than serial if serial is used. serial is limiting the number of workers, that could be further limited with max_concurrent.
The calculation of the percentage of fails is done according to the iterator.batch_size and the number of failed hosts. As iterator.batch_size and also failed_hosts is not changed by the implementation of max_concurrrent I do not see how this could be affected.
As max_concurrent is only temporary limiting the number of workers without changing the task or the batch size I do not see how this could affect run_once as there is no way to use max_concurrent to force to not use any workers. The expected result is the same as without max_concurrent.
I do not see how max_concurrent with the temporary limitation of workers should affect this. Is global fork limit affecting it?
I do not see how max_concurrent with the temporary limitation of workers should affect this. Is global fork limit affecting it?
I do not see how max_concurrent with the temporary limitation of workers should affect this. Is global fork limit affecting it?
I do not see how max_concurrent with the temporary limitation of workers should affect this. Is global fork limit affecting it?
Please let us start an open discussion. |
@t-woerner that is mostly how this implementation works, but the discussion is more about 'how should it work?' I do think yours is one of the simplest approaches by having it be a subset of existing workers, but I expect users to do something like the following: serial: 3 forks: 5 max_concurrent: 5 and expect an expansion on serial. Even with current code, they should at least get a warning that you can never exceed min(serial, forks) .. though i'm not as sure as you are about the actual behaviour (need to test). Another example, when combining max_concurrent: X with run_once ... i would also expect a warning or error since those settings are in conflict and we can only obey one. Its simpler with serial/fork since run_once is clearly more specific (on the task vs play and config) but when both are on the task there is no clear way to set expectations (see loop/when issues). It is not only mapping out 'desired behaviour' its also responding to conflicts and giving the user feedback about incompatibilities. FYI, the discussion is always open, it just has lacked someone pushing it to the forefront. |
/me still thinks this ought to be a per-play, per-role, per-block, per-task directive named forks. Which would influence the global/command-line forks option. Could even be ansible_forks if need be. |
I used the name max_concurrent exactly because of the current behaviour. The number of workers is limited by forks and also the number of hosts in the current batch. I would not expect a simply expansion in this case. The serial option might have been added because of an issue with controller, nodes, used software or environment. This is the same as max_concurrent. I added this to the role to be able to successfully deploy replicas. Right now it is 2 using the same master without getting into trouble, but with some enhancements this might increase to higher values. This can then be adapted with the version of the software for example. But it should not automatically be increased. Information about a low serial setting with a high forks setting might be good to have. This might also be good for settings in other levels. But most likely people will only see this while debugging.
I think it should be possible to add a conflict test with run_once on the task level, but it will not be simple to add a test like this by looking at other levels.
Testing and giving feedback of all settings of all levels (command line, play, blocks, tasks, ...) that might conflict or influence others is really way more work and also invasive than this PR is supposed to be and to be honest it is out of scope of this PR in my opinion. It is something global that needs to be started independently.
|
What priority do you see for this PR? If it is going to be part of 2.8, then it has high priority and I will be able to spend more time. But if it needs to wait till 2.9 or later, then it is low priority and will move down to the bottom of my work plan. |
@t-woerner I hope this can ship with Ansible v2.8. |
To be completely honest, this may not ship with 2.8. We are evaluating the further impact of this with a new feature for selecting the process model (threading vs forking) which is in progress and intended to land in 2.9. The impact of this work could actually cause issues with that planned feature, which could be negative if accepted first. |
run_once: yes | ||
- block: | ||
- name: "Test 1 (max forks: 3)" | ||
command: python |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of python
this should be utilizing ansible_python_interpreter
, potentially falling back to another python.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ansible_playbook_python, since you are executing on "localhosts" (i assume connection = local)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have fixed this in the test case.
Any updates about threading vs forking? |
To my knowledge, we are working through some testing decisions about how we will properly test both process models without overloading the CI infrastructure, but still get enough coverage. |
With ansible_python_interpreter defined in inventory file using ansible_playbook_python. Signed-off-by: Thomas Woerner <twoerner@redhat.com>
199aa8d
to
e31cc8d
Compare
According to https://docs.ansible.com/ansible/latest/roadmap/ROADMAP_2_9.html the Beta 1 Feature (No new functionality (including modules/plugins) to any code) is in less than a month. Will the threading and forking work get merged for 2.9 still? There has not been an update for #44280 since June 21st. |
Merged #60702 which supersedes this. |
With this patch it is possible to limit the number of concurrent task runs for the task where it has been added. This is similar to forks, but affects only one task. It can be used to serialize one or more tasks.
SUMMARY
The ability to limit concurrent task executions for a specific task would help ansible-freeipa to deploy a bigger number of replicas and dependant clients in a cluster environment in a nearly parallel way.
Right now it is not possible to install several replicas with FreeIPA at the same time due to conflicts in the CA configuration step. For ansible-freeipa the installers have been split up into smaller pieces already to be able to replace some of the parts with new roles later on. With this patch in ansible it is possible to have a nearly parallel installation as only the affected step need to be executed in a serial way. The remaining tasks in the role can be done in parallel.
The creation of all replicas with
forks:1
is resulting in a by far longer deployment time. Also the proposals from issue #12170 are not working as the registered output of previous tasks is needed.This fixes #12170
This fixes #24037
ISSUE TYPE
ANSIBLE VERSION
ADDITIONAL INFORMATION
Excerpt from the tasks/install.yml file used to install the replica with the new
forks
directive:Parallel execution without
forks: 1
:Serial execution with
forks: 1
: