fix race condition and KeyError exception in executor (#9335)
Previously, it was possible that `Executor.supports_fancy_output` would
flip-flop between True and False if a thread was updating a section.
This could lead to a crash when an operation got different reponses as
it made progress.
`Executor.supports_fancy_output` reflects the value of the underlying
cleo Formatter used by the Output object. The Formatter is shared by any
SectionOutputs derived by that Output object.
If a thread (tA) is in the middle of `Formatter.remove_format` while
updating a section, the flag to show decorator support is temporarily
toggled off and then restored. This opens a window where another thread
could get an incorrect answer when querying `supports_fancy_output`.
If a parallel thread (tB) queries `supports_fancy_output` and sees it is
False, the operation will not get added to the Executor's _sections
dictionary. If tB's operation progresses after tA has restored the
decorator value and attempts to write out progress information it will
call `Executor._write`, see that `supports_fancy_output` is now True and
attempt to find the operation in the _sections dictionary, however there
will not be an entry for that operation due to the earlier query that
returned False.
This causes tB to throw a KeyError and causes the install to shutdown.
Now, the Executor queries and caches whether the Output is decorated
during init. This value is used in `supports_fancy_output` so as to not
be affected by changes to the underlying Formatter object during section
updates.
Signed-off-by:
Vincent Fazio <vfazio@gmail.com>
Loading
Please register or sign in to comment