Flow-IPC 1.0.0
Flow-IPC project: Full implementation reference.
Namespaces | Classes | Typedefs | Functions | Variables
ipc::transport::struc Namespace Reference

Sub-module of Flow-IPC module ipc::transport providing transmission of structured messages specifically. More...

Namespaces

namespace  error
 Analogous to ipc::transport::error but applies to the sub-namespace ipc::transport::struc – errors having to do with structured messaging.
 
namespace  shm
 Segregates zero-copy/SHM implementations of concepts residing in parent namespace ipc::transport::struc proper – most notably the concepts ipc::transport::struc::Struct_builder and ipc::transport::struc::Struct_reader – and items related to them.
 
namespace  sync_io
 sync_io-pattern counterparts to async-I/O-pattern object types in parent namespace ipc::transport::struc.
 

Classes

class  Channel
 Owning and wrapping a pre-connected transport::Channel peer (an endpoint of an established channel over which unstructured messages and optionally native handles can be transported), this template is the central pillar of the ipc::transport::struc (structured layer), capable of communicating structured capnp-schema-based messages (and native handles). More...
 
class  Channel_base
 Channel base that contains non-parameterized public items such as tag types and constants. More...
 
class  Heap_fixed_builder
 Implements Struct_builder concept by straightforwardly allocating fixed-size segments on-demand in the regular heap and serializing directly inside those segments. More...
 
class  Heap_fixed_builder_capnp_message_builder
 A capnp::MessageBuilder used by Heap_fixed_builder: similar to a capnp::MallocMessageBuilder with the FIXED_SIZE alloc-strategy but with framing space around the allocated segment(s). More...
 
class  Heap_reader
 Implements Struct_reader concept by straightforwardly interpreting a serialization by Heap_fixed_builder or any other builder that produces segments directly readable via SegmentArrayMessageReader. More...
 
class  Msg_in
 A structured in-message instance suitable as received and emittable (to user) by struc::Channel. More...
 
class  Msg_in_impl
 Internally used (data-free) addendum on-top of Msg_in which makes the protected API public instead. More...
 
class  Msg_mdt_out
 Internally used (data-free) addendum on-top of Msg_out; really an alias to Msg_out<schema::detail::StructuredMessage>, where the latter is the internal-use set of metadata schema, with a convenience public mutating API wrapping around capnp-generated mutator API for things like message ID. More...
 
class  Msg_out
 A structured out-message suitable to be sent via struc::Channel::send(). More...
 
class  Msg_out_impl
 Internally used (data-free) addendum on-top of Msg_out which makes the protected API public instead. More...
 
struct  Null_session
 Value for Struct_builder::Session when no extra information is needed when serializing Struct_builder for subsequent sending to another process. More...
 
class  Struct_builder
 A documentation-only concept defining the behavior of an object capable of zero-copy-serializing, similar to capnp::MessageBuilder but geared to transmission over pipe-like IPC transports. More...
 
class  Struct_reader
 A documentation-only concept that is, conceptually, roughly what capnp::MessageReader is to capnp::MessageBuilder, to be used on an in-message serialized by a counterpart Struct_builder, having been transmitted over an IPC transmitter of blobs. More...
 

Typedefs

template<typename Channel_obj , typename Message_body >
using Channel_via_heap = Channel< Channel_obj, Message_body, Heap_fixed_builder::Config, Heap_reader::Config >
 Convenience alias: Use this when constructing a struc::Channel with tag Channel_base::S_SERIALIZE_VIA_HEAP. More...
 
using Capnp_msg_builder_interface = ::capnp::MessageBuilder
 Alias for capnp's MessageBuilder interface. Rationale: as part of our API, we use our identifier style. More...
 
using Session_token = boost::uuids::uuid
 A type used by struc::Channel for internal safety/security/auth needs. More...
 
using Segment_ptrs = std::vector< flow::util::Blob * >
 Sequence of 1+ Blob pointers to blobs which must stay alive while these pointers may be dereferenced, intended here to refer to a capnp serialization of a capnp-struct. More...
 
using msg_id_t = uint64_t
 Message ID uniquely identifying outgoing message (Msg_out, among all other Msg_outs), per channel; and similarly incoming message (Msg_in, among Msg_ins), per channel. More...
 

Functions

std::ostream & operator<< (std::ostream &os, const Heap_fixed_builder &val)
 Prints string representation of the given Heap_fixed_builder to the given ostream. More...
 
std::ostream & operator<< (std::ostream &os, const Heap_reader &val)
 Prints string representation of the given Heap_reader to the given ostream. More...
 
template<typename Message_body , typename Struct_builder_t >
std::ostream & operator<< (std::ostream &os, const Msg_out< Message_body, Struct_builder_t > &val)
 Prints string representation of the given Msg_out to the given ostream. More...
 
template<typename Message_body , typename Struct_reader_config >
std::ostream & operator<< (std::ostream &os, const Msg_in< Message_body, Struct_reader_config > &val)
 Prints string representation of the given Msg_in to the given ostream. More...
 
template<typename Channel_obj , typename Message_body , typename Struct_builder_config , typename Struct_reader_config >
std::ostream & operator<< (std::ostream &os, const Channel< Channel_obj, Message_body, Struct_builder_config, Struct_reader_config > &val)
 Prints string representation of the given struc::Channel to the given ostream. More...
 

Variables

const Session_token NULL_SESSION_TOKEN = boost::uuids::nil_uuid()
 A value for which .is_nil() is true. More...
 
const Null_session NULL_SESSION
 The only necessary value of empty-type Null_session. More...
 

Detailed Description

Sub-module of Flow-IPC module ipc::transport providing transmission of structured messages specifically.

See ipc::transport doc header. As that notes, the big daddy here is struc::Channel.

Be aware of sub-namespace ipc::transport::struc::shm which concerns itself with end-to-end-zero-copyable messages leveraging in-SHM storage. Normally there's no need for the user to know or worry about it, but for advanced applications, particularly extensions and customizations, one might delve into this area of the code. Otherwise it'll be used silently as important glue between various systems. Your journey would like start with the struc::Builder concept doc header which would then lead you to struc::shm::Builder impl. That might lead you to specific SHM-providers like ipc::shm::classic.

Typedef Documentation

◆ Capnp_msg_builder_interface

using ipc::transport::struc::Capnp_msg_builder_interface = typedef ::capnp::MessageBuilder

Alias for capnp's MessageBuilder interface. Rationale: as part of our API, we use our identifier style.

Definition at line 67 of file struc_fwd.hpp.

◆ Channel_via_heap

template<typename Channel_obj , typename Message_body >
using ipc::transport::struc::Channel_via_heap = typedef Channel<Channel_obj, Message_body, Heap_fixed_builder::Config, Heap_reader::Config>

Convenience alias: Use this when constructing a struc::Channel with tag Channel_base::S_SERIALIZE_VIA_HEAP.

See Channel_base::Serialize_via_heap doc header for when/how to use.

Tip: Sync_io_obj member alias will get you the sync_io-pattern counterpart.

Unable to put it in ..._fwd.hpp, because it relies on nested class inside incomplete type.

Definition at line 460 of file heap_serializer.hpp.

◆ msg_id_t

using ipc::transport::struc::msg_id_t = typedef uint64_t

Message ID uniquely identifying outgoing message (Msg_out, among all other Msg_outs), per channel; and similarly incoming message (Msg_in, among Msg_ins), per channel.

0 is a sentinel value and not a valid user message ID. A message ID pertains to a sent or received instance of a user-created Msg_out (and its in-message countrepart Msg_in). A given Msg_out can be sent 2+ times through a given struc::Channel and even a different struc::Channel; a different message ID will pertain to each of those times for a given struc::Channel. Therefore there is no msg_id_t inside a user Msg_out.

This type is in the public API, as the message ID is made available in certain contexts for:

It can also be used as a sequence number and is therefore assigned from sequence 1, 2, ... (0 is sentinel).

Rationale for type used

Needs to be big enough to where there's no chance it overflows in a given channel for a given direction. Assume 1 billion messages per second, or about 2^30 msg/s. That would take 2^(64-30), or 2^34, seconds, or over 500 years, to overflow. So this should be fine. Moreover overflow is fine in that case, in practice, if this is used only as a unique ID; it would however in theory present problems if used as a sequence number.

Definition at line 145 of file struc_fwd.hpp.

◆ Segment_ptrs

using ipc::transport::struc::Segment_ptrs = typedef std::vector<flow::util::Blob*>

Sequence of 1+ Blob pointers to blobs which must stay alive while these pointers may be dereferenced, intended here to refer to a capnp serialization of a capnp-struct.

In each Blob [begin(), end()) is the serialization itself; and space before begin() and starting with end() may be reserved for framing prefix/postfix to preserve zero-copy when transmitting such serializations over an IPC "wire."

Definition at line 122 of file struc_fwd.hpp.

◆ Session_token

using ipc::transport::struc::Session_token = typedef boost::uuids::uuid

A type used by struc::Channel for internal safety/security/auth needs.

See in particular struc::Channel constructors, both the regular-channel one and the session-master-channel one. That said: The user of ipc::transport (aided by ipc::session) structured layer shall generally be unconcerned with this, in practice, as ipc::session machinery will take care of:

  • setting up the session master struc::Channel which will generate this token during initial setup (log-in); and
  • setting up further struc::Channels as requested by the user (the preceding bullet's token shall be passed to each new struc::Channel and expected internally in all messages).

However, if one plans to create a struc::Channel directly (as ipc::session does), then one must have some limited understanding of this guy's existence (if not the internal details).

As you can see: internally it is a UUID (RFC 4122 Universally Unique IDentifier) which is 128 bits (16 bytes) in size. It's also a POD (Plain Old Data object), meaning it's ctor-free (direct-initialized) and can be memcpy()d around and such. See boost.uuid docs (which are simple).

Use and rationale thereof

A session master channel struc::Channel, operating in server mode during the log-in phase, will (as of this writing anyway) generate this using the boost.uuid random UUID generator. From that point on all channels spawned through that guy (by ipc::session) will be cted with that token value; and all messages both in those channels and the original master channel (after the log-in message exchange) will send this value and ensure any in-message has that value (or immediately hose the channel – auth failure). This is a safety (not really security, due to the lack of token invalidation at least) measure. It will reduce chances that "wires get crossed," and a message goes into the wrong channel somehow.

That's how it's used. Is the random-generator method of UUID generation acceptable for this use?

A bit of research (starting in the RFC perhaps; or Wikipedia) shows that collisions are so cosmically rare as to make it, quite officially, a non-concern. Even if one does not accept that, however, suppose a collision does occur: two channels happen to generate the same UUID on the same machine around the same time. This (essentially impossible) scenario would not cause either channel to break; it would only allow (in theory) a token check to succeed where it shouldn't, if the fabled wires-crossed scenario occurred. This is an acceptable level of risk.

Conversely, perhaps using UUIDs for this is overkill. 128 bits isn't heavy, but perhaps something smaller – maybe even much smaller, like 32 bits or even 16 – would improve perf without really reducing effectiveness given the above rationale. Indeed that's worth considering but only in the phase where perf optimization is the explicit goal. Until then (if that even happens) the ability to use the nice boost.uuid library instead of rolling our own jankier/smaller UUID-like thing (or whatever) is well worth the alleged perf cost.

Todo:
Look into whether something smaller that RFC 4122 UUIDs can and should be used for Session_token. This would be for perf but may well be unnecessary. See discussion near this to-do.

Definition at line 113 of file struc_fwd.hpp.

Function Documentation

◆ operator<<() [1/5]

template<typename Channel_obj , typename Message_body , typename Struct_builder_config , typename Struct_reader_config >
std::ostream & operator<< ( std::ostream &  os,
const Channel< Channel_obj, Message_body, Struct_builder_config, Struct_reader_config > &  val 
)

Prints string representation of the given struc::Channel to the given ostream.

Parameters
osStream to which to write.
valObject to serialize.
Returns
os.

◆ operator<<() [2/5]

std::ostream & operator<< ( std::ostream &  os,
const Heap_fixed_builder val 
)

Prints string representation of the given Heap_fixed_builder to the given ostream.

Parameters
osStream to which to write.
valObject to serialize.
Returns
os.

Definition at line 132 of file heap_serializer.cpp.

◆ operator<<() [3/5]

std::ostream & operator<< ( std::ostream &  os,
const Heap_reader val 
)

Prints string representation of the given Heap_reader to the given ostream.

Parameters
osStream to which to write.
valObject to serialize.
Returns
os.

Definition at line 180 of file heap_serializer.cpp.

◆ operator<<() [4/5]

template<typename Message_body , typename Struct_reader_config >
std::ostream & operator<< ( std::ostream &  os,
const Msg_in< Message_body, Struct_reader_config > &  val 
)

Prints string representation of the given Msg_in to the given ostream.

Parameters
osStream to which to write.
valObject to serialize.
Returns
os.

Definition at line 1407 of file msg.hpp.

◆ operator<<() [5/5]

template<typename Message_body , typename Struct_builder_t >
std::ostream & operator<< ( std::ostream &  os,
const Msg_out< Message_body, Struct_builder_t > &  val 
)

Prints string representation of the given Msg_out to the given ostream.

Namely it prints via Msg_out::to_ostream()`; be sure to read perf notes on that!

Parameters
osStream to which to write.
valObject to serialize.
Returns
os.

Definition at line 1108 of file msg.hpp.

Variable Documentation

◆ NULL_SESSION

const Null_session ipc::transport::struc::NULL_SESSION

◆ NULL_SESSION_TOKEN

const Session_token ipc::transport::struc::NULL_SESSION_TOKEN = boost::uuids::nil_uuid()