> IOW the solution to the problem is to use threads. You can see here
why I said what I did: threads specifically avoid this problem and the
only way for asyncio to avoid it is to use threads.
In the case of the above example, I'd say it's more so "use coroutines by default and threads as needed" rather than just using threads, but fair enough. I'll concede that point.
> For instance, maybe during testing (with debug=True), your
DNS lookups are always reasonably fast, but then some time after
deployment, you find that they're stalling you out. How much effort is
it to change this over? How many other things are going to be slow,
and can you find them all?
That's very situationally dependent, but for any IO-bound call with a variable time where async isn't an option (either because it's not available, standardized, widespread, etc.), I'd advise using loop.run_in_executor()/to_thread() preemptively. This is easier said than done of course and it's very possible for some to be glossed over. If it's missed though, I don't think it's too much effort to change it over; IMO the main challenge is more so with locating all of them in production for a large, existing codebase.
>
3) Steven D'Aprano is terrified of them and will rail on you for using threads.
Haha, I've somehow completely missed that. I CC'd Steven in the response, since I'm curious as to what he has to say about that.
>
Take your pick. Figure out what your task needs. Both exist for good reasons.
Completely agreed, threads and coroutines are two completely different approaches, with neither one being clearly superior for all situations. Even as someone who's invested a significant amount of time in helping to improve asyncio recently, I'll admit that I decently often encounter users that would be better off using threads. Particularly for code that isn't performance or resource critical, or when it involves a reasonably small number of concurrent operations that aren't expected to scale in volume significantly. The fine-grained control over context switching (which can be a pro or a con), shorter switch delay, and lower resource usage from coroutines isn't always worth the added code complexity.