diff --git a/src/ipc/libmultiprocess/include/mp/proxy-io.h b/src/ipc/libmultiprocess/include/mp/proxy-io.h index ec9a15396e1..da817d8d268 100644 --- a/src/ipc/libmultiprocess/include/mp/proxy-io.h +++ b/src/ipc/libmultiprocess/include/mp/proxy-io.h @@ -884,6 +884,7 @@ struct Listener kj::Own m_receiver; std::optional m_max_connections; size_t m_active_connections{0}; + bool m_accept_failure_logged{false}; }; template @@ -892,8 +893,9 @@ void _Listen(const std::shared_ptr& listener, EventLoop& loop, InitImp if (listener->atCapacity()) return; auto* receiver = listener->m_receiver.get(); - loop.m_task_set->add(receiver->accept().then( + auto accept = receiver->accept().then( [&loop, &init, listener](kj::Own&& stream) { + listener->m_accept_failure_logged = false; ++listener->m_active_connections; _Serve(loop, kj::mv(stream), init, [&loop, &init, listener] { const bool resume_accept{listener->atCapacity()}; @@ -902,6 +904,17 @@ void _Listen(const std::shared_ptr& listener, EventLoop& loop, InitImp if (resume_accept) _Listen(listener, loop, init); }); _Listen(listener, loop, init); + }); + loop.m_task_set->add(accept.catch_( + [&loop, &init, listener](kj::Exception&& exception) -> kj::Promise { + if (exception.getType() != kj::Exception::Type::OVERLOADED) return kj::mv(exception); + if (!listener->m_accept_failure_logged) { + listener->m_accept_failure_logged = true; + MP_LOG(loop, Log::Warning) << "IPC listener accept hit a temporary resource limit. Retrying after 100 ms."; + } + return loop.m_io_context.provider->getTimer().afterDelay(100 * kj::MILLISECONDS).then([&loop, &init, listener] { + _Listen(listener, loop, init); + }); })); }