Use a single stream redirector for both setup and predict (#2069)
Currently for models that provide a non-async predict function we have
two stream redirectors wrapping stdout/stderr.
We think this entering/exiting the stream redirector context multiple times
may have been causing unusual bugs, particularly with models that use
libraries like `tqdm` to render progress bars and other manipulation.
This PR changes this behaviour to use either the `StreamRedirector` or
(newly renamed) `SimpleStreamRedirector` based on whether the predict
is defined with an async function or not. We now use the same redirector
for module loading, setup and prediction.
The interrogation of the predict function now happens higher up the stack
in http.py when we read the input/output types using
`config.get_predictor_types`. This now returns an additional value
`is_async` which is `True` when an async function is defined.
This is then passed down the stack into the worker which uses it to select an
appropriate stream redirector instance. In future when we come to support
async setup functions we may need to revisit whether `is_async` is the
correct term for the worker argument, `use_simple_stream` or similar might
be more appropriate.
This has been tested with both sync and async models including flux-dev
and seems to be working correctly.