| Flow-IPC 1.0.2
    Flow-IPC project: Full implementation reference. | 
Implements Session concept on the Client_app end: a Session_mv that first achieves PEER state by connecting to an opposing Session_server_mv via Client_session_mv::sync_connect(). More...
#include <client_session.hpp>
| Public Types | |
| using | Base = Session_mv< Client_session_impl_t > | 
| Short-hand for our base class. To the user: note its publicAPI is inherited.  More... | |
|  Public Types inherited from ipc::session::Session_mv< Client_session_impl_t > | |
| using | Channel_obj = typename Impl::Channel_obj | 
| Implements Session API per contract.  More... | |
| using | Channels = typename Impl::Channels | 
| Container ( vector<>) of Channel_obj.  More... | |
| using | Mdt_payload_obj = typename Impl::Mdt_payload_obj | 
| Implements Session API per contract.  More... | |
| using | Mdt_builder = typename Impl::Mdt_builder | 
| Implements Session API per contract.  More... | |
| using | Mdt_builder_ptr = typename Impl::Mdt_builder_ptr | 
| Implements Session API per contract.  More... | |
| using | Mdt_reader_ptr = typename Impl::Mdt_reader_ptr | 
| Implements Session API per contract.  More... | |
| using | Structured_channel = typename transport::struc::Channel_via_heap< Channel_obj, Message_body > | 
| Implements Session API per contract.  More... | |
| using | Structured_msg_builder_config = typename Impl::Structured_msg_builder_config | 
| Implements Session API per contract.  More... | |
| using | Structured_msg_reader_config = typename Impl::Structured_msg_builder_config | 
| Implements Session API per contract.  More... | |
| Public Member Functions | |
| template<typename On_passive_open_channel_handler , typename Task_err > | |
| Client_session_mv (flow::log::Logger *logger_ptr, const Client_app &cli_app_ref, const Server_app &srv_app_ref, Task_err &&on_err_func, On_passive_open_channel_handler &&on_passive_open_channel_func) | |
| Constructs (passive-opens allowed form) in NULL state.  More... | |
| template<typename Task_err > | |
| Client_session_mv (flow::log::Logger *logger_ptr, const Client_app &cli_app_ref, const Server_app &srv_app_ref, Task_err &&on_err_func) | |
| Constructs (passive-opens disallowed form) in NULL state.  More... | |
| Mdt_builder_ptr | mdt_builder () | 
| Implements Session API per contract; plus usable to generate blank mdtargument for advanced sync_connect() overload.  More... | |
| bool | sync_connect (Error_code *err_code=0) | 
| To be invoked in NULL state only, and not as-if default-cted, it synchronously and non-blockingly attempts to connect to an opposing Session_server; and synchronously reports failure or success, the latter showing*thishas entered PEER state.  More... | |
| bool | sync_connect (const typename Base::Mdt_builder_ptr &mdt, typename Base::Channels *init_channels_by_cli_req_pre_sized=0, typename Base::Mdt_reader_ptr *mdt_from_srv_or_null=0, typename Base::Channels *init_channels_by_srv_req=0, Error_code *err_code=0) | 
| Identical to the simpler sync_connect() overload but offers added advanced capabilities: metadata exchange; initial-channel opening.  More... | |
|  Public Member Functions inherited from ipc::session::Session_mv< Client_session_impl_t > | |
| Session_mv () | |
| Implements Session API per contract.  More... | |
| Session_mv (Session_mv &&src) | |
| Implements Session API per contract.  More... | |
| Session_mv (const Session_mv &)=delete | |
| Copy ction is disallowed. | |
| ~Session_mv () | |
| Implements Session API per contract.  More... | |
| Session_mv & | operator= (Session_mv &&src) | 
| Implements Session API per contract.  More... | |
| Session_mv & | operator= (const Session_mv &)=delete | 
| Copy assignment is disallowed. | |
| Mdt_builder_ptr | mdt_builder () | 
| Implements Session API per contract.  More... | |
| bool | open_channel (Channel_obj *target_channel, const Mdt_builder_ptr &mdt, Error_code *err_code=0) | 
| Implements Session API per contract.  More... | |
| bool | open_channel (Channel_obj *target_channel, Error_code *err_code=0) | 
| Implements Session API per contract.  More... | |
| const Session_token & | session_token () const | 
| Implements Session API per contract.  More... | |
| transport::struc::Heap_fixed_builder::Config | heap_fixed_builder_config () | 
| Utility that obtains a heap-based (non-zero-copy) Struct_builder::Config, constructed with the most efficient yet safe values, for transport::struc::Msg_out (out-messages) compatible with Structured_channel upgraded-from Channel_obj channels opened via *thisSession_mv.  More... | |
| transport::struc::Heap_reader::Config | heap_reader_config () | 
| Deserializing counterpart to non- staticheap_fixed_builder_config().  More... | |
| flow::log::Logger * | get_logger () const | 
| Returns logger (possibly null).  More... | |
| const flow::log::Component & | get_log_component () const | 
| Returns log component.  More... | |
| Related Functions | |
| (Note that these are not member functions.) | |
| template<typename Client_session_impl_t > | |
| std::ostream & | operator<< (std::ostream &os, const Client_session_mv< Client_session_impl_t > &val) | 
| Prints string representation of the given Client_session_mvto the givenostream.  More... | |
|  Related Functions inherited from ipc::session::Session_mv< Client_session_impl_t > | |
| std::ostream & | operator<< (std::ostream &os, const Session_mv< Client_session_impl_t > &val) | 
| Prints string representation of the given Session_mvto the givenostream.  More... | |
| Additional Inherited Members | |
|  Static Public Member Functions inherited from ipc::session::Session_mv< Client_session_impl_t > | |
| static transport::struc::Heap_fixed_builder::Config | heap_fixed_builder_config (flow::log::Logger *logger_ptr) | 
| Utility that obtains a heap-based (non-zero-copy) Struct_builder::Config, constructed with the most efficient yet safe values, for transport::struc::Msg_out (out-messages) compatible with Structured_channel upgraded-from Channel_obj channels opened via this Session_mv type.  More... | |
| static transport::struc::Heap_reader::Config | heap_reader_config (flow::log::Logger *logger_ptr) | 
| Deserializing counterpart to staticheap_fixed_builder_config().  More... | |
|  Static Public Attributes inherited from ipc::session::Session_mv< Client_session_impl_t > | |
| static constexpr schema::ShmType | S_SHM_TYPE | 
| Implements Session API per contract.  More... | |
| static constexpr bool | S_SHM_ENABLED | 
| Implements Session API per contract.  More... | |
| static constexpr bool | S_MQS_ENABLED | 
| Compile-time-known constant indicating whether Channel_obj shall use a blobs pipe over message queues (MQs).  More... | |
| static constexpr bool | S_SOCKET_STREAM_ENABLED | 
| Compile-time-known constant indicating whether Channel_obj shall use socket stream for any type of pipe.  More... | |
|  Protected Types inherited from ipc::session::Session_mv< Client_session_impl_t > | |
| using | Impl = Client_session_impl_t | 
| Short-hand for pImpl-lite impl type. This shall be the deepest impl sub-class desired.  More... | |
| using | Session_base_obj = typename Impl::Session_base_obj | 
| Short-hand for Impl's Session_base super-class.  More... | |
| using | Impl_ptr = std::experimental::propagate_const< boost::movelib::unique_ptr< Impl > > | 
| Short-hand for const-respecting wrapper around Impl for the pImpl idiom. See impl().  More... | |
|  Protected Member Functions inherited from ipc::session::Session_mv< Client_session_impl_t > | |
| const Session_base_obj & | base () const | 
| Provides constaccess to Session_base super-object.  More... | |
| Impl_ptr & | impl () | 
| pImpl target; particularly for sub-classes that must add to the above publicAPI.  More... | |
| const Impl_ptr & | impl () const | 
| pImpl target; particularly for sub-classes that must add to the above publicAPI.  More... | |
Implements Session concept on the Client_app end: a Session_mv that first achieves PEER state by connecting to an opposing Session_server_mv via Client_session_mv::sync_connect().
See overview of Session hierarchy in namespace ipc::session doc header; then come back here if desired.
It is unusual to use Client_session_mv template directly. If you do wish to set up a client-side session peer, and you do not require SHM support, then use Client_session alias template. The client-specific API, particularly ctor and sync_connect(), is in Client_session_mv and documented here. The side-agnostic API – active once PEER state is achieved – is described by Session (concept) doc header and implemented concretely by Session_mv which is our public, non-virtual super-class.
If you do wish to set up a client-side session peer, but you do require SHM support, then use shm::classic::Client_session or similar (for other SHM-provider(s)). However Client_session (hence Client_session_mv to which it aliases) is its super-class, and until PEER state is reached its API remains the only relevant API to use. Once Client_session_mv::sync_connect() puts *this into PEER state, super-class Session_mv (= Session concept) API continues to be relevant. Also in PEER state SHM-relevant additional API members (e.g., shm::classic::Session_mv::app_shm()`) become of interest.
Summary hierarchy:
session_shm()...; suitable for transport::struc::Channel_base::Serialize_via_session_shm)We may refer to Client_session_mv as Client_session below; particularly since it is likeliest used in that form by the user.
Per the Session concept a Client_session is open/capable of operation when in PEER state only. A Client_session object is always in one of 2 states:
To get from NULL state to PEER state: Use Session_server on the other side. On this side construct a Client_session (always in NULL state) and invoke sync_connect() which will synchronously and non-blockingly try to move to PEER state (mission accomplished). If the connect fails, it will stay in NULL state. Being moved-from makes a *this as-if default-cted; therefore also moves to NULL state.
Once in PEER state Client_session simply follows Session concept semantics. At this stage our super-class Session_mv implements that concept in particular. See either doc header (Session, Session_mv).
A related reminder:
async_accept() or both may optionally specify that 1+ init-channels be opened before this and the opposing Session is in PEER state and emitted to user. This may be a sufficient replacement of, or complementary to, active-open/passive-open APIs available once the Session is in PEER state/emitted to user. If not sufficient:Without networking, the other side (Session_server) either exists/is listening; or no. Connecting is a synchronous, non-blocking operation; so an async_connect() API in this context only makes life harder for the user. (However, there are some serious plans to add a networking-capable counterpart (probably via TCP at least) to Native_socket_stream and therefore Client_session_mv; such a networky-client-session class will almost certainly have an async_connect(), while its sync_connect() will probably become potentially blocking.)
*this becomes network-enabled, open_channel() too will need an async form most likely, while existing open_channel() would become potentially-blocking.These follow the Session concept policies.
Once in PEER state, error handling follows the Session concept (= Session_mv concrete class) doc header. Up to that point (in NULL state) there are no public asynchronous operations; there is just sync_connect() which succeeds or fails synchronously and quickly.
Session_mv is the highest (public) super-class and begins the pImpl-lite-for-movability technique. It pImpl-wraps the Session-concept impl methods/stuff. Client_session_mv merely repeats the same technique but on the API additions at its own level; in particular the explicit ctors and especially sync_connect().
The impl object is available via Session_mv::impl() (which is protected). What type does this object have though? Answer: Client_session_impl_t, our template param! This shall be the proper ..._impl internal-use type that matches the level of API (public sub-class) the user chose: E.g.:
So basically each of the public-API types visible to the user adds the pImpl-wrapping of the methods of the ..._impl type matching their name; and the public/movable-API hierarchy has a parallel internal/non-movable hierarchy, both using public/non-virtual inheritance.
| Client_session_impl_t | An implementation detail. Use one of the aliases prescribed near the top of this doc header to set this correctly. | 
Definition at line 143 of file client_session.hpp.
| using ipc::session::Client_session_mv< Client_session_impl_t >::Base = Session_mv<Client_session_impl_t> | 
Short-hand for our base class. To the user: note its public API is inherited. 
Definition at line 150 of file client_session.hpp.
| 
 | explicit | 
Constructs (passive-opens allowed form) in NULL state.
To be useful, invoke sync_connect() next.
| logger_ptr | Logger to use for logging subsequently. | 
| cli_app_ref | Properties of this client application. The address is copied; the object is not copied. | 
| srv_app_ref | Properties of the opposing server application. The address is copied; the object is not copied. | 
| on_err_func | On-error handler. See Session concept doc header for semantics. | 
| on_passive_open_channel_func | On-passive-open handler. See Session concept doc header for semantics. | 
| On_passive_open_channel_handler | See Session concept doc header for semantics. | 
| Task_err | See Session concept doc header for semantics. | 
Definition at line 376 of file client_session.hpp.
| 
 | explicit | 
Constructs (passive-opens disallowed form) in NULL state.
To be useful, invoke sync_connect() next.
| logger_ptr | Logger to use for logging subsequently. | 
| cli_app_ref | Properties of this client application. The address is copied; the object is not copied. | 
| srv_app_ref | Properties of the opposing server application. The address is copied; the object is not copied. | 
| on_err_func | On-error handler. See Session concept doc header for semantics. | 
| Task_err | See Session concept doc header for semantics. | 
Definition at line 390 of file client_session.hpp.
| Mdt_builder_ptr ipc::session::Client_session_mv< Client_session_impl_t >::mdt_builder | ( | ) | 
Implements Session API per contract; plus usable to generate blank mdt argument for advanced sync_connect() overload. 
That is: can additionally be invoked in NULL state (before sync_connect() or between a failed attempt and the next attempt). The return value can be used only as follows; otherwise undefined behavior results:
| bool ipc::session::Client_session_mv< Client_session_impl_t >::sync_connect | ( | const typename Base::Mdt_builder_ptr & | mdt, | 
| typename Base::Channels * | init_channels_by_cli_req_pre_sized = 0, | ||
| typename Base::Mdt_reader_ptr * | mdt_from_srv_or_null = 0, | ||
| typename Base::Channels * | init_channels_by_srv_req = 0, | ||
| Error_code * | err_code = 0 | ||
| ) | 
Identical to the simpler sync_connect() overload but offers added advanced capabilities: metadata exchange; initial-channel opening.
The other overload is identical to sync_connect(mdt_builder(), nullptr, nullptr, nullptr, err_code) and requires the opposing async_accept() to similarly not use the corresponding features.
Client may wish to provide information in some way, but without a structured channel – or any channel – yet available, this provides an opportunity to do so in a structured way with a one-off message available at session open, together with the opposing Session object itself.
Similarly to how it is optionally done on a per-channel-open basis (open_channel()): call mdt = mdt_builder(); fill out the resulting capnp structure *mdt; then pass mdt to sync_connect(). Opposing async_accept() shall receive deserializable Mdt_reader together with the freshly-opened Session, though they may choose to ignore it.
To omit using this feature, skip the "fill out the resulting capnp structure" step. You must still call mdt_builder() and pass-in the result. (The other overload does so.)
This is the reverse of the above. Whatever the opposing server chose to supply as server->client metadata shall be deserializable at *mdt_from_srv_or_null on successful return from sync_connect(). If mdt_from_srv_or_null is null, the srv->cli metadata shall be ignored.
Once the session is open, open_channel() and the on-passive-open handler may be used to open channels at will. In many use cases, however, a certain number of channels is required immediately before work can really begin (and, frequently, no further channels are even needed). For convenience (to avoid asynchrony/boiler-plate) the init-channels feature will pre-open a requested # of channels making them available right away, together with the freshly-open session – to both sides.
The client may request 0 or more init-channels. They shall be opened and placed into *init_channels_by_cli_req_pre_sized; its ->size() at entry to the method indicates the number of channels requested. If null, it is treated as if ->size() == 0, meaning no init-channels-by-client-request are opened.
This is the reverse of the above. The opposing side shall request 0 or more init-channels-by-server-request; that number of channels shall be opened; and they will be placed into *init_channels_by_srv_req which shall be ->resize()d accordingly on successful return from sync_connect().
init_channels_by_srv_req being null is allowed, but only if the opposing server requests 0 init-channels-by-server-request. Otherwise an error shall be emitted (see below).
| mdt | See above. | 
| init_channels_by_cli_req_pre_sized | See above: null or pointer to container of Channel_objwith.size()specifying how many channels this side is requesting to be opened on its behalf; each element will be move-assigned a PEER-stateChannel_objon success. Recommend simply ct-ing with(n)or.resize(n)which loads it with default-cted (NULL-state) objects to be replaced. null is treated same as.empty(). | 
| mdt_from_srv_or_null | See above: null or pointer to Readerof metadata which shall be set for access on success. | 
| init_channels_by_srv_req | See above: null or pointer to container of Channel_objwhich shall be.clear()ed and replaced by a container of PEER-stateChannel_objon success the number being specified by the opposing (server) side. The number may be zero. null is allowed if and only if the number is zero; otherwise error::Code::S_INVALID_ARGUMENT is emitted. | 
| err_code | See other sync_connect() overload. Note the above target (pointer) args are touched only if no error is emitted via this standard Flow error reporting mechanism. | 
Definition at line 406 of file client_session.hpp.
| bool ipc::session::Client_session_mv< Client_session_impl_t >::sync_connect | ( | Error_code * | err_code = 0 | ) | 
To be invoked in NULL state only, and not as-if default-cted, it synchronously and non-blockingly attempts to connect to an opposing Session_server; and synchronously reports failure or success, the latter showing *this has entered PEER state. 
Failure means *this remains in NULL state.
If invoked outside of NULL state, or if it is as-if default-cted (i.e., default-cted or moved-from), this returns false and otherwise does nothing.
Note that *this (modulo moves) that has entered PEER state can never change state subsequently (even on transmission error); once a PEER, always a PEER.
While details are internal, abstractly speaking this is determined by the Server_app passed to the ctor. Internal detail (for exposition/general knowledge):
Client_session will connect, and all other internally used cross-process resources (sockets, MQs, SHM pools...) are similarly segregated among different instances of the Server_app-described application.Server_apps. Now it knows "where" to connect in order to open the session; so it won't accidentally connect to some old zombie instance of the Server_app (its PID wouldn't be in the CNS file any longer) or another application entirely (its PID file would be located elsewhere and never accessed by this sync_connect()).Then sync_connect() will quickly fail (file-not-found or connection-refused error). Shouldn't we supply some API to await its appearance and actively listening? Answer: Probably not. Why? Answer: Consider the situation where the PID file is there, but it belongs to a now-exited instance of the Server_app; let's say it is currently suspended or restarting. sync_connect() will fail then too: There is nothing listening (anymore) at the advertised PID. So it'll quickly fail (connection-refused error). So then we'd also need an API to await an active server's appearance whether or not the PID exists. That leads to the following to-do:
false if and only if invoked outside of NULL state; or if *this is as-if default-cted.| err_code | See flow::Error_codedocs for error reporting semantics. Error_code generated: session::error::Code::S_OBJECT_SHUTDOWN_ABORTED_COMPLETION_HANDLER (destructor called, canceling all pending ops; spiritually identical toboost::asio::error::operation_aborted), interprocess-mutex-related errors (probably from boost.interprocess) w/r/t reading the CNS (PID file), file-related system errors w/r/t reading the CNS (PID file) (see Session_server doc header for background), error::Code::S_CLIENT_NAMESPACE_STORE_BAD_FORMAT (bad CNS contents), those emitted by transport::Native_socket_stream::sync_connect(), those emitted by transport::struc::Channel::send(), those emitted by transport::struc::Channel via on-error handler (most likely transport::error::Code::S_RECEIVES_FINISHED_CANNOT_RECEIVE indicating graceful shutdown of opposing process coincidentally during log-in procedure, prematurely ending session while it was starting), error::Code::S_CLIENT_MASTER_LOG_IN_RESPONSE_BAD, error::Code::S_INVALID_ARGUMENT (other side expected other sync_connect() overload with non-nullinit_channels_by_srv_reqarg). | 
Definition at line 400 of file client_session.hpp.
| 
 | related | 
Prints string representation of the given Client_session_mv to the given ostream. 
| os | Stream to which to write. | 
| val | Object to serialize. | 
os. Definition at line 419 of file client_session.hpp.