Flow-IPC 1.0.1
Flow-IPC project: Public API.
Public Types | Public Attributes | Related Functions | List of all members
ipc::session::App Struct Reference

A description of an application in this ipc::session inter-process communication universe. More...

#include <app.hpp>

Inheritance diagram for ipc::session::App:
[legend]

Public Types

using Master_set = boost::unordered_map< std::string, App >
 Suggested type for storing master repository or all Appss. See App doc header for discussion.
 

Public Attributes

std::string m_name
 Brief application name, readable to humans and unique across all other applications' names; used both as a short programmatic key in shared resource naming (including as a folder in Shared_name for kernel-persistent resources and addresses; and in path names – such as PID file name – in the file system). More...
 
fs::path m_exec_path
 Absolute, lexically normalized canonical path to the executable entity (which is not a directory), as it would appear in a command line or exec()-like invocation when actually invoking the application. More...
 
util::user_id_t m_user_id
 The application must run as this user ID (UID). Files and other shared resources shall have this owner.
 
util::group_id_t m_group_id
 The application must run as this group ID (GID). Files and other shared resources shall have this owner.
 

Related Functions

(Note that these are not member functions.)

std::ostream & operator<< (std::ostream &os, const App &val)
 Prints string representation of the given App to the given ostream. More...
 

Detailed Description

A description of an application in this ipc::session inter-process communication universe.

An application is, at least roughly speaking, 1-1 with a distinct executable presumably interested in communicating with another such executable. A process is an instance of an application that has begun execution at some point.

An App is a description of an application, and typically used (at least after program initialization, before actual IPC begins) only as supertype of Client_app and/or Server_app, it is possible that 2+ Apps exist but describe one actual application but in different roles. 2+ such Apps must have all members equal to each other respectively. In particular see App::m_name.

This is a data store (and a simple one). The same holds of Client_app and Server_app. As of this writing there are no rigid rules as to the existence of an App/Client_app/Server_app with this or that stored inside. Make them all day long, if you want! More restrictions shall come into play only when passing various App objects and sub-objects (in some form) to ipc::session APIs, most notably the Session concept and buddies.

However, to be useful, we suggest the following convention. Some key ipc::session APIs may rely on it.

App, Client_app, Server_app registry conventions

Thus one would end up with, after initialization of each process wishing to participate in a given IPC universe:

There should be no need, from this moment on, to copy any App, Client_app, or Server_app. It shall be passed by const reference.

Friends And Related Function Documentation

◆ operator<<()

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

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

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

Member Data Documentation

◆ m_exec_path

fs::path ipc::session::App::m_exec_path

Absolute, lexically normalized canonical path to the executable entity (which is not a directory), as it would appear in a command line or exec()-like invocation when actually invoking the application.

Formally (refer to cppreference.com filesystem::path doc page):

  • There is no root-name: No Windows drive letters ("C:"), no network file share ("//share_name"), etc.
  • It is a Unix path: Only forward-slash is used as separator, and that character always is a separator.
  • It is absolute: It starts with forward-slash.
  • It is lexically normalized: See reference, but essentially it means no more than one slash in a row, no dot components, no dot-dot components. (Note: dots and dot-dots can appear – but an entire component cannot comprise solely such a sequence; where component means: a thing preceded by slash and succeeded by slash or end-of-path.)

Do note that because of the "as it would appear in a command line..." requirement this indirectly restricts how processes are to be invoked in this system: always via 1, absolute, lexically normal path to the executable. (Do also note this is still not necessary force an unambiguous way to invoke an application installed at a given location: sym-links, at least, introduce an infinite number of ways to refer to the same binary. That said, at least lexical normalization can be done programmatically in fs, and sym-link following path resolution is also separately supplied by fs.)

◆ m_name

std::string ipc::session::App::m_name

Brief application name, readable to humans and unique across all other applications' names; used both as a short programmatic key in shared resource naming (including as a folder in Shared_name for kernel-persistent resources and addresses; and in path names – such as PID file name – in the file system).

Convention: mandated use as key

Neither App nor any nearby sub-class or alias of App (Client_app, Server_app) shall be used as the key type in an associative container (e.g., set, unordered_map). Instead App::m_name shall be used as the key when lookup by distinct application is desired. Two scenarios come to mind:

  • You want to store a set of applications fitting some criterion/a, but this is not some master repository of App objects in the first place – rather it is referring to some subset of such a master repository.
    • Then, store simply a set or unordered_set (etc.) of std::string m_names.
      • Rationale: The basic desired operation here is an exitence-check (is application X present, based on some definition of present?). m_name is by definition guaranteed to be distinct from all others. Hence storing such strings alone is sufficient and reasonably efficient while also not relying on App address uniqueness for lookup (which, while efficient, is a pain to maintain).
  • You want to store some master repository of App objects, with all their config such as UID, GID, etc.
    • Then, store a map or unordered_map, with the keys being std::string m_names, while the values are filled-out App objects (or objects of App sub-class) – with the guarantee that M[name].m_name == name for all names in any such M.
      • Rationale: Same as above; but in addition to being able to perform existence-check by m_name, one can also iterate through the master details of all the applications and/or lookup a given application's master details.

Due to these conventions:

  • We do not supply the usual complement of associative-container "stuff" for App and buddies: equality, less-than, hashing. We do not want to encourage direct App storage that way.
  • The idea is: When such storage is desired, use that usual complement of associative-container "stuff" that is already supplied for std::string, as applied to App::m_name.

Digression regarding rationale: Why use m_name, and not (say) const App*, as the key in associative lookups? Answer: It was considered. Due to the infrequency of such lookups, combined with the debug-friendliness/expressiveness of referring to a distinct app by its user-readable name, the lookup-by-name convention felt more straightforward and convenient. Plus, the address of an object stored in a container may change while it is being built, which would add an element of brittleness. One could also use an iterator as a key, but then the registry container would be mandated to be iteratator-stable-under-insertion, and that brings an annoying host of worries. Indexing by string name is solid by comparison, if a bit slower.

Conventions: Naming

Must begin with an ASCII alphabetical character and otherwise consist of only ASCII alphanumerics and underscores. While these are partially conventions driven by style (for example, dashes could also be allowed – we just do not want them to be, so that underscores are always the word-separator used consistently), the following is an important guarantee for related Shared_name and fs::path semantics:

  • Must not contain a util::Shared_name::S_SEPARATOR.
  • Must not contain a forward-slash or any other file system path separator.
  • Must not contain a dot or any other conceivable extension separator (other than underscore).

Therefore:

  • In Shared_name paths one can embed m_name by preceding and/or succeeding it with a util::Shared_name::S_SEPARATOR, thus making it a full or partial folder name.
  • In file system paths one can embed m_name by preceding and/or succeeding it with a forward-slash, thus making it a full or partial directory name.
  • In either: one can embed m_name by preceding and/or succeeding it with a dot as an extension separator.

So if m_name is "abc_def" one can do things like "/some/dir/abc_def/some_file" and "/some/dir/abc_def.pid/file" and "/some/dir/prefix.abc_def.3". I.e., m_name can be safely used as a conceptual "token," even when combined with path/name separators and dot-extension naming.


The documentation for this struct was generated from the following files: