diff --git a/src/ripple/rpc/Yield.h b/src/ripple/rpc/Yield.h index f7e0aaa9e..73dffafbc 100644 --- a/src/ripple/rpc/Yield.h +++ b/src/ripple/rpc/Yield.h @@ -78,10 +78,15 @@ private: struct YieldStrategy { enum class Streaming {no, yes}; + enum class UseCoroutines {no, yes}; /** Is the data streamed, or generated monolithically? */ Streaming streaming = Streaming::no; + /** Are results generated in a coroutine? If this is no, then the code can + never yield. */ + UseCoroutines useCoroutines = UseCoroutines::no; + /** How many bytes do we emit before yielding? 0 means "never yield due to number of bytes sent". */ std::size_t byteYieldCount = 0; diff --git a/src/ripple/rpc/impl/Yield.cpp b/src/ripple/rpc/impl/Yield.cpp index c7f3b3fcc..4f4d3a289 100644 --- a/src/ripple/rpc/impl/Yield.cpp +++ b/src/ripple/rpc/impl/Yield.cpp @@ -71,6 +71,9 @@ YieldStrategy makeYieldStrategy (Section const& s) ys.streaming = get (s, "streaming") ? YieldStrategy::Streaming::yes : YieldStrategy::Streaming::no; + ys.useCoroutines = get (s, "use_coroutines") ? + YieldStrategy::UseCoroutines::yes : + YieldStrategy::UseCoroutines::no; ys.byteYieldCount = get (s, "byte_yield_count"); ys.accountYieldCount = get (s, "account_yield_count"); ys.transactionYieldCount = get (s, "transaction_yield_count"); diff --git a/src/ripple/server/impl/ServerHandlerImp.cpp b/src/ripple/server/impl/ServerHandlerImp.cpp index 565bef5f8..c63e3249b 100644 --- a/src/ripple/server/impl/ServerHandlerImp.cpp +++ b/src/ripple/server/impl/ServerHandlerImp.cpp @@ -180,12 +180,24 @@ ServerHandlerImp::onRequest (HTTP::Session& session) auto detach = session.detach(); - RPC::SuspendCallback suspend ( - [this, detach] (RPC::Suspend const& suspend) { - processSession (detach, suspend); - }); - RPC::Coroutine coroutine (suspend); - coroutine.run(); + if (setup_.yieldStrategy.useCoroutines == + RPC::YieldStrategy::UseCoroutines::yes) + { + RPC::SuspendCallback suspend ( + [this, detach] (RPC::Suspend const& suspend) { + processSession (detach, suspend); + }); + RPC::Coroutine coroutine (suspend); + coroutine.run(); + } + else + { + getApp().getJobQueue().addJob ( + jtCLIENT, "RPC-Client", + [=] (Job&) { + processSession (detach, RPC::Suspend()); + }); + } } void