Adding loop_control.notify_scope#56817
Conversation
bcoca
left a comment
There was a problem hiding this comment.
Also brought up at irc meeting, general consensus is +1 on feature, you might get people bikeshedding on name later though
1634bf4 to
2065f8d
Compare
| return items | ||
|
|
||
| def _execute(self, variables=None): | ||
| def _execute(self, variables=None, notify_scope='task'): |
There was a problem hiding this comment.
I would turn notify_scope parameter into an instance variable, self._notify_scope. That way you don't have to pass it around.
There was a problem hiding this comment.
👍 to making this an instance attribute.
| self._task.notify is not None and ( | ||
| notify_scope != 'per_loop_item' or ( | ||
| notify_scope == 'per_loop_item' and | ||
| result['changed']))): |
There was a problem hiding this comment.
This is probably just me but I had a hard time parsing that. I would change notify_scope != 'per_loop_item' into notify_scope == 'task' and put it all on the one or two lines maybe. Not a blocker, of course.
There was a problem hiding this comment.
This doesn't account for invalid values. I'm wondering if this would be better as a boolean value rather than a string field. Something like notify_per_item with a default of False.
Are there other values for this option that would make it better suited to a string than a boolean?
If we do keep it as a string value, maybe the options could be task, item or task, per_item. Just throwing out ideas.
There was a problem hiding this comment.
This is easier to read:
if self._task.notify is not None:
if notify_per_loop_item:
if result['changed']:
result['_ansible_notify'] = self._task.notify
else:
result['_ansible_notify'] = self._task.notifyOr using the existing string option:
if self._task.notify is not None:
if notify_scope not in ['task', 'per_loop_item']:
raise AnsibleError("Invalid option '{0}' given for notify_scope. Valid options are "
"'task' or 'per_loop_item'".format(to_text(notify_scope)))
elif notify_scope == 'per_loop_item':
if result['changed']:
result['_ansible_notify'] = self._task.notify
else:
result['_ansible_notify'] = self._task.notifyThere was a problem hiding this comment.
This doesn't account for invalid values.
Yeah, I realized that when suggested notify_per_item below, too ;-) I was wondering if we had anything like choices for FieldAttribute so we didn't have to check for invalid types here in the code but not that I could find.
There was a problem hiding this comment.
The way we have done this before is via something like _validate_debugger. That method effectively does this, but for debugger
There was a problem hiding this comment.
Nice. So I'd go with _validate_$whatever_name_we_bikeshed method to check for invalid values. Unless we decide to use a boolean.
| loop_control: | ||
| extended: yes | ||
|
|
||
| Notification scope in the loop |
|
Bikeshedding: can we maybe do something like Unless we plan to add more options in the future. |
| return items | ||
|
|
||
| def _execute(self, variables=None): | ||
| def _execute(self, variables=None, notify_scope='task'): |
There was a problem hiding this comment.
👍 to making this an instance attribute.
| self._task.notify is not None and ( | ||
| notify_scope != 'per_loop_item' or ( | ||
| notify_scope == 'per_loop_item' and | ||
| result['changed']))): |
There was a problem hiding this comment.
This doesn't account for invalid values. I'm wondering if this would be better as a boolean value rather than a string field. Something like notify_per_item with a default of False.
Are there other values for this option that would make it better suited to a string than a boolean?
If we do keep it as a string value, maybe the options could be task, item or task, per_item. Just throwing out ideas.
| self._task.notify is not None and ( | ||
| notify_scope != 'per_loop_item' or ( | ||
| notify_scope == 'per_loop_item' and | ||
| result['changed']))): |
There was a problem hiding this comment.
This is easier to read:
if self._task.notify is not None:
if notify_per_loop_item:
if result['changed']:
result['_ansible_notify'] = self._task.notify
else:
result['_ansible_notify'] = self._task.notifyOr using the existing string option:
if self._task.notify is not None:
if notify_scope not in ['task', 'per_loop_item']:
raise AnsibleError("Invalid option '{0}' given for notify_scope. Valid options are "
"'task' or 'per_loop_item'".format(to_text(notify_scope)))
elif notify_scope == 'per_loop_item':
if result['changed']:
result['_ansible_notify'] = self._task.notify
else:
result['_ansible_notify'] = self._task.notify|
|
||
| - name: Set handler variables to known value | ||
| set_fact: | ||
| handler_one: null |
There was a problem hiding this comment.
You could use ~ rather than null.
| - name: Test all handlers were run | ||
| assert: | ||
| that: | ||
| - handler_one != None |
There was a problem hiding this comment.
Using a test rather than a comparison is a bit more reliable. Types with Jijna can be a pain.
| - handler_one != None | |
| - handler_one is not none |
| ------------------------------ | ||
| .. versionadded:: 2.9 | ||
|
|
||
| By default, if each loop item triggers different notification target, all targets for all items get triggered even if |
There was a problem hiding this comment.
| By default, if each loop item triggers different notification target, all targets for all items get triggered even if | |
| By default, if each loop item triggers a different notification target, all targets for all items get triggered even if |
SUMMARY
When using
notifyin a loop, notification targets for all loop items are triggered even if only single loop item has been changed. This PR is adding aloop_controltoggle which allows to trigger notification targets only for changed items of the loop.To the attention of @bcoca.
ISSUE TYPE
Feature Pull Request
COMPONENT NAME
loop_controlADDITIONAL INFORMATION
See more details and examples in the documentation included in the PR.