-
Notifications
You must be signed in to change notification settings - Fork 612
Add MAX_EXECUTIONS environment variable limit #5272
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
base: master
Are you sure you want to change the base?
Changes from all commits
acb464c
6d5eb78
4b80b3b
da2f31d
c6203fd
5326c42
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -114,12 +114,26 @@ def schedule_utask_mains(): | |
| task.pubsub_task.cancel_lease_ack() | ||
|
|
||
|
|
||
| def _get_max_executions(): | ||
| """Returns the MAX_EXECUTIONS limit as an int, or None if invalid/unset.""" | ||
| val = environment.get_value('MAX_EXECUTIONS') | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, and one final comment: |
||
| if not val: | ||
| return None | ||
| try: | ||
| return int(val) | ||
| except ValueError: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should instead loudly fail and exit if the environment variable is wrong. It would surface configuration issues immediately, right before we start the task loop, whereas logging an error gets a bit lost in the noise. |
||
| logs.error(f'Invalid value for MAX_EXECUTIONS: {val}') | ||
| environment.remove_key('MAX_EXECUTIONS') | ||
| return None | ||
|
|
||
|
|
||
| def task_loop(): | ||
| """Executes tasks indefinitely.""" | ||
| # Defer heavy task imports to prevent issues with multiprocessing.Process | ||
| from clusterfuzz._internal.bot.tasks import commands | ||
|
|
||
| clean_exit = False | ||
| execution_count = 0 | ||
| while True: | ||
| stacktrace = '' | ||
| exception_occurred = False | ||
|
|
@@ -191,6 +205,13 @@ def task_loop(): | |
| time.sleep(utils.random_number(1, failure_wait_interval)) | ||
| break | ||
|
|
||
| execution_count += 1 | ||
| max_executions = _get_max_executions() | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should move to above the while loop. There is no reason to re-check the environment variable for a new value on every iteration - it should have the same value for the lifetime of the whole process. This also ties in with loudly failing on invalid values. If we check the value before we even enter the loop, we will immediately surface configuration errors instead of waiting until after we run a task to notice the error. Finally, consider switching to a for loop instead. It looks like max_executions = _get_max_executions()
for _ in itertools.repeat(None, times=max_executions):
...See https://docs.python.org/3/library/itertools.html#itertools.repeat I guess the downside of the for loop is that it's harder to log the clean exit message. |
||
| if max_executions and execution_count >= max_executions: | ||
| logs.info(f'Reached MAX_EXECUTIONS limit ({max_executions}). Exiting.') | ||
| clean_exit = True | ||
| break | ||
|
|
||
| task_payload = task.payload() if task else None | ||
| return stacktrace, clean_exit, task_payload | ||
|
|
||
|
|
||
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 guess this works, but do we even need it? And why not use
return_valueinstead?