28#include <flow/log/log.hpp>
30#include <boost/move/unique_ptr.hpp>
31#include <boost/array.hpp>
87template<
typename Client_session_t>
89 private boost::noncopyable
153 bool enable_hndl_transport =
true,
154 bool sans_shm_transport =
false);
182 template<
typename Type>
196 ::capnp::Capability::Client
get_main();
301template<
typename Session_server_t>
303 public flow::log::Log_context,
304 public kj::TaskSet::ErrorHandler,
305 private boost::noncopyable
372 template<
typename Main_
interface_func>
373 explicit Ez_rpc_server(flow::log::Logger* logger_ptr, Main_interface_func&& main_interface_func,
376 bool enable_hndl_transport =
true);
417 template<
typename Main_
interface_func,
typename Transport_method_func>
418 explicit Ez_rpc_server(flow::log::Logger* logger_ptr, Main_interface_func&& main_interface_func,
421 bool enable_hndl_transport,
422 Transport_method_func&& transport_method_func);
470 void taskFailed(kj::Exception&& exc)
override;
510template<
typename Client_session_t>
514 bool enable_hndl_transport,
bool sans_shm_transport) :
518 m_rpc_ctx(logger_ptr, &m_this_thread_kj_io->m_kj_io, cli_app_ref, srv_app_ref, enable_hndl_transport)
520 using ::capnp::makeRpcClient;
522 if (sans_shm_transport)
533template<
typename Client_session_t>
534template<
typename Type>
537 return get_main().template castAs<Type>();
540template<
typename Client_session_t>
550 using Word = ::capnp::word;
554 constexpr size_t VAT_ID_SZ_WORDS = 4;
556 array<Word, VAT_ID_SZ_WORDS> scratch;
559 auto host_id = message.getRoot<
Vat_id>();
560 host_id.setSide(::capnp::rpc::twoparty::Side::SERVER);
562 return m_rpc_sys->bootstrap(host_id);
565template<
typename Client_session_t>
568 return &m_this_thread_kj_io->m_kj_io.waitScope;
571template<
typename Client_session_t>
574 return m_this_thread_kj_io->m_kj_io.provider;
577template<
typename Client_session_t>
580 return m_this_thread_kj_io->m_kj_io.lowLevelProvider;
583template<
typename Client_session_t>
589template<
typename Client_session_t>
595template<
typename Client_session_t>
598 return os <<
"[cli_ctx[" << val.
rpc_context() <<
"]]@" << &val;
603template<
typename Session_server_t>
604template<
typename Main_
interface_func>
608 bool enable_hndl_transport) :
609 Ez_rpc_server(logger_ptr, std::move(main_interface_func), srv_app_ref, cli_app_master_set_ref,
610 enable_hndl_transport,
611 [](auto&&...) {
return false; })
616template<
typename Session_server_t>
617template<
typename Main_
interface_func,
typename Transport_method_func>
621 bool enable_hndl_transport,
622 Transport_method_func&& transport_method_func) :
624 m_main_interface_func(std::move(main_interface_func)),
625 m_transport_method_func(std::move(transport_method_func)),
627 m_ctx_srv(get_logger(), &m_this_thread_kj_io->m_kj_io, srv_app_ref, cli_app_master_set_ref),
630 FLOW_LOG_INFO(
"Ez_rpc_srv [" << *
this <<
"]: Started Ez_rpc_server. Will listen for/service concurrent clients.");
635template<
typename Session_server_t>
638 using ::capnp::makeRpcServer;
639 using kj::heapString;
640 using Transport_method_func =
decltype(m_transport_method_func);
642 using Server_context_ptr =
typename Server_context_obj::Ptr;
647 Server_context_ptr m_rpc_ctx;
650 using Rpc_bundle_ptr = boost::movelib::unique_ptr<Rpc_bundle>;
660 m_tasks.add(m_ctx_srv.accept(enable_hndl_transport,
661 [](
auto&&...) { return 0; },
662 Transport_method_func(m_transport_method_func))
663 .then([
this, enable_hndl_transport]
664 (
auto&& accept_result)
mutable
666 accept_loop(enable_hndl_transport);
672 const auto& cli_app = *(accept_result.m_context->session()->client_app());
673 FLOW_LOG_INFO(
"Ez_rpc_srv [" << *
this <<
"]: Accepted session from client (app [" << cli_app <<
"]); "
674 "creating RPC-system; and resuming listening for more.");
676 auto& network = *(accept_result.m_context->vat_network());
677 auto main_interface = m_main_interface_func(cli_app);
678 Rpc_bundle_ptr rpc_bundle{
new Rpc_bundle{ std::move(accept_result.m_context),
679 makeRpcServer(network, std::move(main_interface)) }};
685 m_tasks.add(rpc_bundle->m_rpc_ctx->vat_network()->on_disconnect().attach(std::move(rpc_bundle)));
687 [
this, enable_hndl_transport](
auto&& kj_exception)
mutable
699 accept_loop(enable_hndl_transport);
701 FLOW_LOG_WARNING(
"Ez_rpc_srv [" << *
this <<
"]: Session-connect started but failed with error; ignoring and "
702 "resuming listening; error was: [" << heapString(kj_exception.getDescription()).cStr() <<
"].");
706template<
typename Session_server_t>
709 kj::throwFatalException(std::move(exc));
712template<
typename Session_server_t>
715 return &m_this_thread_kj_io->m_kj_io.waitScope;
718template<
typename Session_server_t>
721 return m_this_thread_kj_io->m_kj_io.provider;
724template<
typename Session_server_t>
727 return m_this_thread_kj_io->m_kj_io.lowLevelProvider;
730template<
typename Session_server_t>
737template<
typename Session_server_t>
743template<
typename Session_server_t>
746 return os <<
"[ctx_srv[" << val.
context_server() <<
"]]@" << &val;
Simple utility: a capnp MessageBuilder operating over a single, contiguous, user-supplied area in vir...
bool sync_connect(typename Session_obj::Channels *init_channels_by_cli_req_pre_sized=nullptr, typename Session_obj::Channels *init_channels_by_srv_req=nullptr)
To be invoked successfully at most once, it synchronously and non-blockingly attempts to connect to a...
bool sync_connect_sans_shm_transport(typename Session_obj::Channels *init_channels_by_cli_req_pre_sized=nullptr, typename Session_obj::Channels *init_channels_by_srv_req=nullptr)
Identical to sync_connect() with same signature but disables zero-copy transport.
Vat_network * vat_network()
Returns pointer to Session_vat_network established for use in your rpc::Rpc_system; or null if no syn...
Much like capnp::EzRpcClient but uses Flow-IPC zero-copy machinery.
Client_session_t Client_session_obj
Convenience alias for template arg.
Ez_rpc_client(flow::log::Logger *logger_ptr, const session::Client_app &cli_app_ref, const session::Server_app &srv_app_ref, bool enable_hndl_transport=true, bool sans_shm_transport=false)
Constructs us by immediately (and non-blockingly, synchronously) establishing the capnp-RPC session.
Ez_rpc_kj_io::Ptr m_this_thread_kj_io
Handle to this thread's KJ event-loop (shared between all other Ez_rpc_client and Ez_rpc_server insta...
const Client_context_obj & rpc_context() const
Returns reference to immutable core Client_context.
kj::AsyncIoProvider * get_io_provider()
Get the underlying AsyncIoProvider set up for this thread.
kj::LowLevelAsyncIoProvider * get_low_level_io_provider()
Get the underlying LowLevelAsyncIoProvider set up for this thread.
Client_context_obj m_rpc_ctx
This really does the vast majority of the work, doing Client_context::sync_connect() right in ctor.
std::optional< Rpc_system > m_rpc_sys
Conventionally-client-side Rpc_system created using the zero-copy VatNetwork inside m_rpc_ctx.
Type::Client get_main()
Obtain bootstrap interface handle (per other get_main() overload) type-interpreted as implementing th...
kj::WaitScope * get_wait_scope()
Get the wait-scope for this thread's KJ event-loop which allows one to synchronously wait on promises...
Internal-use thread-local singleton-style access to a kj::AsyncIoContext which, for each given thread...
Much like capnp::EzRpcServer but uses Flow-IPC zero-copy machinery.
Ez_rpc_server(flow::log::Logger *logger_ptr, Main_interface_func &&main_interface_func, const session::Server_app &srv_app_ref, const session::Client_app::Master_set &cli_app_master_set_ref, bool enable_hndl_transport=true)
Constructs us by immediately beginning background listen.
kj::TaskSet m_tasks
Similar to Context_server::m_tasks.
Context_server_obj m_ctx_srv
The big daddy that produces Server_contexts as clients connect to us.
Session_server_t Session_server_obj
Convenience alias for template arg.
const Context_server_obj & context_server() const
Returns reference to immutable core Context_server.
kj::LowLevelAsyncIoProvider * get_low_level_io_provider()
Get the underlying LowLevelAsyncIoProvider set up for this thread.
void taskFailed(kj::Exception &&exc) override
Implements kj::TaskSet::ErrorHandler API.
void accept_loop(bool enable_hndl_transport)
The asynchronously-infinitely-self-perpetuating loop that accepts and then services any incoming sess...
flow::Function< bool(const session::Client_app &)> m_transport_method_func
The decider of whether to use zero-copy transport (false) or not (true) depending on which Client_app...
kj::WaitScope * get_wait_scope()
Get the wait-scope for this thread's KJ event-loop which allows one to synchronously wait on promises...
kj::AsyncIoProvider * get_io_provider()
Get the underlying AsyncIoProvider set up for this thread.
flow::Function<::capnp::Capability::Client(const session::Client_app &)> m_main_interface_func
The computer of the bootstrap capnp-interface depending on which Client_app is connecting.
Ez_rpc_kj_io::Ptr m_this_thread_kj_io
Handle to this thread's KJ event-loop (shared between all other Ez_rpc_client and Ez_rpc_server insta...
The mirror of an opposing PEER-state Client_context, as generated via successful Context_server::acce...
Provides Flow-IPC's integration with Cap'n Proto's Remote Procedure Call (RPC) layer,...
::capnp::rpc::twoparty::VatId Vat_id
Flow-IPC-styled alias for the node ID in a Session_vat_network or TwoPartyVatNetwork: namely an enume...
std::ostream & operator<<(std::ostream &os, const Client_context< Client_session_t > &val)
Prints string representation of the given Client_context to the given ostream.
::capnp::RpcSystem< Vat_id > Rpc_system
Concrete capnp::RpcSystem to be used with Session_vat_network or TwoPartyVatNetwork.
boost::asio::mutable_buffer Blob_mutable
Short-hand for a mutable blob somewhere in memory, stored as exactly a void* and a size_t.
Log_component
The flow::log::Component payload enumeration containing various log components used by Flow-IPC inter...
flow::Function< Signature > Function
Short-hand for polymorphic functor holder which is very common. This is essentially std::function.
An App that is used as a client in at least one client-server IPC split.
boost::unordered_map< std::string, Client_app > Master_set
Type for storing master repository of all Client_apps. See App doc header for discussion.
An App that is used as a server in at least one client-server IPC split.