Repository: actix/actix-web (language: rust)

Issue:
Destructor of awc::Client panics when the runtime is stopped
## Expected Behavior

I create a `SystemRunner` and an `awc::Client` inside of it. I perform an HTTP query using the client. I stop and drop the runtime. The runtime is dropped and everything works.

## Current Behavior

When `SystemRunner` is dropped there is a panic inside `<awc::client::pool::ConnectionPoolInner<Io> as core::ops::drop::Drop>::drop::{{closure}}`. The destructor of `ConnectionPool` goes over all the pooled connections and tries to spawn a future to close them. It calls `tokio::time::timeout`, but the runtime is stopped and it panics with:
```
thread 'main' panicked at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/awc-3.5.0/src/client/pool.rs:317:22:
there is no reactor running, must be called from the context of a Tokio 1.x runtime
```
See the reproduction steps for a full backtrace.

## Possible Solution

I didn't expect `ConnectionPool` to spawn futures in the destructor. Is this allowed? I thought it's an antipattern, but I'm not a Tokio expert.

Maybe there could be a check like `if runtime.is_running() {do_stuff();} else {dont_do_stuff_it_will_panic();}`?

I see that by default `disconnect_timeout` is `None` for new clients, so this destructor isn't triggered for most of them. Entering the panicking code path requires the user to create a custom connection using `Connector::new()` and using TLS. Only then `disconnect_timeout` is `Some` and the bug gets triggered.
I tried to set `disconnect_timeout` back to `None`, but it's impossible because `Connector` doesn't have a method for that. It'd be nice to add it.

I see that for tcp connections there's this line:
```rust
let tcp_config = self.config.no_disconnect_timeout();
```
Which disables disconnect timeout on all tcp connections. Maybe the same could be done for TLS connections?

I worked around the problem by using `force_close()` on the Client. The connections are closed and not returned to the pool, so the destructor doesn't do anything and the bug doesn't trigger.

## Steps to Reproduce the bug

I created a minimal reproducer: https://github.com/jancionear/awc-problem/tree/v2
It worked on two ubuntu Linux machines, didn't work on one Linux VM and Mac. If it doesn't work for you, please try on a different machine. I don't understand runtime destruction at a good enough level to make it reproduce everywhere :/

Steps:
```bash
git clone https://github.com/jancionear/awc-problem --branch v2
cd awc-problem
RUST_BACKTRACE=1 cargo run
```
Expected output:
<details>
<summary> Click to expand (includes a long backtrace) </summary>

```
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s
     Running `target/debug/awc-problem`
OK!
Client has size: 40
thread 'main' panicked at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/awc-3.5.0/src/client/pool.rs:317:22:
there is no reactor running, must be called from the context of a Tokio 1.x runtime
stack backtrace:
   0: rust_begin_unwind
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_fmt
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_display
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/panicking.rs:262:5
   3: tokio::runtime::scheduler::Handle::current::panic_cold_display
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/panic.rs:99:13
   4: tokio::runtime::scheduler::Handle::current
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/runtime/scheduler/mod.rs:106:27
   5: tokio::time::sleep::Sleep::new_timeout
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/time/sleep.rs:257:22
   6: tokio::time::sleep::sleep
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/time/sleep.rs:129:27
   7: awc::client::pool::CloseConnection<Io>::new
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/awc-3.5.0/src/client/pool.rs:317:22
   8: awc::client::pool::ConnectionPoolInner<Io>::close
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/awc-3.5.0/src/client/pool.rs:79:33
   9: <awc::client::pool::ConnectionPoolInner<Io> as core::ops::drop::Drop>::drop::{{closure}}::{{closure}}
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/awc-3.5.0/src/client/pool.rs:117:57
  10: core::iter::traits::iterator::Iterator::for_each::call::{{closure}}
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/traits/iterator.rs:815:29
  11: <alloc::collections::vec_deque::into_iter::IntoIter<T,A> as core::iter::traits::iterator::Iterator>::fold::{{closure}}
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/alloc/src/collections/vec_deque/into_iter.rs:121:56
  12: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ops/function.rs:294:13
  13: core::iter::adapters::map::map_try_fold::{{closure}}
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/adapters/map.rs:96:21
  14: core::iter::traits::iterator::Iterator::try_fold
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/traits/iterator.rs:2411:21
  15: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::try_fold
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/adapters/map.rs:122:9
  16: <alloc::collections::vec_deque::into_iter::IntoIter<T,A> as core::iter::traits::iterator::Iterator>::try_fold
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/alloc/src/collections/vec_deque/into_iter.rs:105:14
  17: <alloc::collections::vec_deque::into_iter::IntoIter<T,A> as core::iter::traits::iterator::Iterator>::fold
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/alloc/src/collections/vec_deque/into_iter.rs:121:15
  18: core::iter::traits::iterator::Iterator::for_each
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/traits/iterator.rs:818:9
  19: <awc::client::pool::ConnectionPoolInner<Io> as core::ops::drop::Drop>::drop::{{closure}}
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/awc-3.5.0/src/client/pool.rs:117:21
  20: core::iter::traits::iterator::Iterator::for_each::call::{{closure}}
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/traits/iterator.rs:815:29
  21: core::iter::traits::iterator::Iterator::fold
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/traits/iterator.rs:2589:21
  22: <hashbrown::map::IntoIter<K,V,A> as core::iter::traits::iterator::Iterator>::fold
             at /rust/deps/hashbrown-0.14.5/src/map.rs:4827:9
  23: <std::collections::hash::map::IntoIter<K,V> as core::iter::traits::iterator::Iterator>::fold
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/collections/hash/map.rs:2332:19
  24: core::iter::traits::iterator::Iterator::for_each
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/traits/iterator.rs:818:9
  25: <awc::client::pool::ConnectionPoolInner<Io> as core::ops::drop::Drop>::drop
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/awc-3.5.0/src/client/pool.rs:114:13
  26: core::ptr::drop_in_place<awc::client::pool::ConnectionPoolInner<alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>>>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  27: core::ptr::drop_in_place<awc::client::pool::ConnectionPool<alloc::rc::Rc<dyn actix_service::Service<awc::client::Connect>+Future = core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<(alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol),awc::client::error::ConnectError>>>+Response = (alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol)+Error = awc::client::error::ConnectError>,alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>>>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  28: core::ptr::drop_in_place<core::option::Option<awc::client::pool::ConnectionPool<alloc::rc::Rc<dyn actix_service::Service<awc::client::Connect>+Future = core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<(alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol),awc::client::error::ConnectError>>>+Response = (alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol)+Error = awc::client::error::ConnectError>,alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>>>>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  29: core::ptr::drop_in_place<awc::client::connector::ConnectorServicePriv<awc::client::connector::TcpConnectorService<awc::client::connector::TcpConnectorInnerService<actix_tls::connect::connector::ConnectorService>>,alloc::rc::Rc<dyn actix_service::Service<awc::client::Connect>+Future = core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<(alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol),awc::client::error::ConnectError>>>+Response = (alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol)+Error = awc::client::error::ConnectError>,tokio::net::tcp::stream::TcpStream,alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>>>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  30: core::ptr::drop_in_place<awc::connect::DefaultConnector<awc::client::connector::ConnectorServicePriv<awc::client::connector::TcpConnectorService<awc::client::connector::TcpConnectorInnerService<actix_tls::connect::connector::ConnectorService>>,alloc::rc::Rc<dyn actix_service::Service<awc::client::Connect>+Future = core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<(alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol),awc::client::error::ConnectError>>>+Response = (alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol)+Error = awc::client::error::ConnectError>,tokio::net::tcp::stream::TcpStream,alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>>>>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  31: <alloc::rc::Rc<T,A> as core::ops::drop::Drop>::drop
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/alloc/src/rc.rs:2193:17
  32: core::ptr::drop_in_place<alloc::rc::Rc<awc::connect::DefaultConnector<awc::client::connector::ConnectorServicePriv<awc::client::connector::TcpConnectorService<awc::client::connector::TcpConnectorInnerService<actix_tls::connect::connector::ConnectorService>>,alloc::rc::Rc<dyn actix_service::Service<awc::client::Connect>+Future = core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<(alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol),awc::client::error::ConnectError>>>+Response = (alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol)+Error = awc::client::error::ConnectError>,tokio::net::tcp::stream::TcpStream,alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>>>>>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  33: core::ptr::drop_in_place<awc::middleware::redirect::RedirectService<awc::connect::DefaultConnector<awc::client::connector::ConnectorServicePriv<awc::client::connector::TcpConnectorService<awc::client::connector::TcpConnectorInnerService<actix_tls::connect::connector::ConnectorService>>,alloc::rc::Rc<dyn actix_service::Service<awc::client::Connect>+Future = core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<(alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol),awc::client::error::ConnectError>>>+Response = (alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol)+Error = awc::client::error::ConnectError>,tokio::net::tcp::stream::TcpStream,alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>>>>>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  34: core::ptr::drop_in_place<actix_service::boxed::ServiceWrapper<awc::middleware::redirect::RedirectService<awc::connect::DefaultConnector<awc::client::connector::ConnectorServicePriv<awc::client::connector::TcpConnectorService<awc::client::connector::TcpConnectorInnerService<actix_tls::connect::connector::ConnectorService>>,alloc::rc::Rc<dyn actix_service::Service<awc::client::Connect>+Future = core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<(alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol),awc::client::error::ConnectError>>>+Response = (alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>,actix_http::Protocol)+Error = awc::client::error::ConnectError>,tokio::net::tcp::stream::TcpStream,alloc::boxed::Box<dyn awc::client::connection::ConnectionIo>>>>>>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  35: core::ptr::drop_in_place<dyn actix_service::Service<awc::connect::ConnectRequest>+Future = core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<awc::connect::ConnectResponse,awc::client::error::SendRequestError>>>+Response = awc::connect::ConnectResponse+Error = awc::client::error::SendRequestError>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  36: <alloc::rc::Rc<T,A> as core::ops::drop::Drop>::drop
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/alloc/src/rc.rs:2193:17
  37: core::ptr::drop_in_place<alloc::rc::Rc<dyn actix_service::Service<awc::connect::ConnectRequest>+Future = core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<awc::connect::ConnectResponse,awc::client::error::SendRequestError>>>+Response = awc::connect::ConnectResponse+Error = awc::client::error::SendRequestError>>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  38: core::ptr::drop_in_place<awc::client::ClientConfig>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  39: core::ptr::drop_in_place<awc::client::Client>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  40: core::ptr::drop_in_place<awc_problem::main::{{closure}}::{{closure}}>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:35:9
  41: core::ptr::drop_in_place<tokio::runtime::task::core::Stage<awc_problem::main::{{closure}}::{{closure}}>>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  42: tokio::runtime::task::core::Core<T,S>::set_stage::{{closure}}
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/runtime/task/core.rs:382:41
  43: tokio::loom::std::unsafe_cell::UnsafeCell<T>::with_mut
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/loom/std/unsafe_cell.rs:16:9
  44: tokio::runtime::task::core::Core<T,S>::set_stage
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/runtime/task/core.rs:382:9
  45: tokio::runtime::task::core::Core<T,S>::drop_future_or_output
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/runtime/task/core.rs:347:13
  46: tokio::runtime::task::harness::cancel_task::{{closure}}
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/runtime/task/harness.rs:453:9
  47: core::ops::function::FnOnce::call_once
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ops/function.rs:250:5
  48: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/panic/unwind_safe.rs:272:9
  49: std::panicking::try::do_call
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/panicking.rs:559:40
  50: __rust_try
  51: std::panicking::try
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/panicking.rs:523:19
  52: std::panic::catch_unwind
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/panic.rs:149:14
  53: tokio::runtime::task::harness::cancel_task
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/runtime/task/harness.rs:452:15
  54: tokio::runtime::task::harness::Harness<T,S>::shutdown
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/runtime/task/harness.rs:247:9
  55: tokio::runtime::task::raw::shutdown
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/runtime/task/raw.rs:311:5
  56: tokio::runtime::task::raw::RawTask::shutdown
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/runtime/task/raw.rs:235:18
  57: tokio::runtime::task::Task<S>::shutdown
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/runtime/task/mod.rs:418:9
  58: tokio::runtime::task::list::LocalOwnedTasks<S>::close_and_shutdown_all
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/runtime/task/list.rs:276:13
  59: tokio::task::local::LocalState::close_and_shutdown_all
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/task/local.rs:1158:9
  60: <tokio::task::local::LocalSet as core::ops::drop::Drop>::drop::{{closure}}
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/task/local.rs:909:17
  61: tokio::task::local::LocalSet::with_if_possible::{{closure}}
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/task/local.rs:758:13
  62: std::thread::local::LocalKey<T>::try_with
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/thread/local.rs:283:12
  63: tokio::task::local::LocalSet::with_if_possible
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/task/local.rs:756:19
  64: <tokio::task::local::LocalSet as core::ops::drop::Drop>::drop
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/task/local.rs:904:9
  65: core::ptr::drop_in_place<tokio::task::local::LocalSet>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  66: core::ptr::drop_in_place<actix_rt::runtime::Runtime>
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ptr/mod.rs:542:1
  67: actix_rt::system::SystemRunner::run_with_code
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/actix-rt-2.10.0/src/system.rs:204:5
  68: actix_rt::system::SystemRunner::run
             at /home/jan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/actix-rt-2.10.0/src/system.rs:186:25
  69: awc_problem::main
             at ./src/main.rs:39:5
  70: core::ops::function::FnOnce::call_once
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Dropped system
```
</details>

## Context

In [nearcore](https://github.com/near/nearcore) we have a `TelemetryActor` which periodically uploads telemetry data using `awc::Client`. We noticed that when the program is shut down it prints a panic originating in the `awc::Client`.
We worked around the problem by forcing the client to close all connections, then there's nothing to destroy at the end: https://github.com/near/nearcore/pull/11914

## Your Environment

<!--- Include as many relevant details about the environment you experienced the bug in -->

- Rust Version (I.e, output of `rustc -V`): `rustc 1.80.1 (3f5fd8dd4 2024-08-06)`
- Actix Web Version: `actix = 0.13.5`, `awc = 3.50`



Discussion / hints:

Fix patch:
diff --git a/awc/CHANGES.md b/awc/CHANGES.md
index a2e51c8d25f..11cb150ab5e 100644
--- a/awc/CHANGES.md
+++ b/awc/CHANGES.md
@@ -2,6 +2,7 @@
 
 ## Unreleased
 
+- Prevent panics on connection pool drop when Tokio runtime is shutdown early.
 - Minimum supported Rust version (MSRV) is now 1.75.
 
 ## 3.5.1
diff --git a/awc/src/client/pool.rs b/awc/src/client/pool.rs
index 1736f2b020a..5d764f72936 100644
--- a/awc/src/client/pool.rs
+++ b/awc/src/client/pool.rs
@@ -76,7 +76,9 @@ where
     fn close(&self, conn: ConnectionInnerType<Io>) {
         if let Some(timeout) = self.config.disconnect_timeout {
             if let ConnectionInnerType::H1(io) = conn {
-                actix_rt::spawn(CloseConnection::new(io, timeout));
+                if tokio::runtime::Handle::try_current().is_ok() {
+                    actix_rt::spawn(CloseConnection::new(io, timeout));
+                }
             }
         }
     }


Test patch: