|
Flow-IPC 3.0.0
Flow-IPC project: Full implementation reference.
|
A description of an application in this ipc::session inter-process communication universe. More...
#include <app.hpp>
Public Types | |
| using | Master_set = boost::unordered_map< std::string, App > |
Type for storing master repository of all Apps. More... | |
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. More... | |
| 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. More... | |
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... | |
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, 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.
Back to the conventions:
set or unordered_set (by App::m_name; see its doc header) available in a centrally-available library; or this *set could simply be a hard-coded C++ extern const; whatever works.*set. (The information regarding which apps are clients, too, can be read from JSON/XML/whatever or hard-coded.)*set of applications.m_allowed_client_apps.)Thus one would end up with, after initialization of each process wishing to participate in a given IPC universe:
*set of Apps (global App registry).*set of Client_apps (global Client_app registry).*set of Server_apps (global Server_app registry), each Server_app listing the m_names of Client_apps referring to the applications that may initiate sessions with it in its immutable Server_app::m_allowed_client_apps.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.
| using ipc::session::App::Master_set = boost::unordered_map<std::string, App> |
Type for storing master repository of all Apps.
See App doc header for discussion.
It is unordered_, simply because there was not any particularly compelling reason to impose an order. (Admittedly: alphabetical order by m_name might have been nice in some contexts, like if someone wanted to pretty-print a Master_set. Ah, well. It is set now. Prints can be tweaked to sort anyway; as of this writing Flow-IPC does not print a Master_set anywhere.)
Using unordered_map (instead of unordered_flat_map) is pretty good here, as this way there is pointer stability. On one hand the implied – not as of this writing formally required – preferred pattern of use is for the user to set up their IPC universe, including these Master_sets, before any IPC happens – and then never change any of the data therein. On the other hand, "implied preferred pattern" be damned, it is conceivable a user would at some point, after giving some API a Master_set, add an App to that set. In that case pointer stability is an asset; any memorized App addresses won't become invalid on rehash.
Performance is not a concern here: lookups are rare; sizes are small. Hence no need to mess with _node_map and so forth.
|
related |
Prints string representation of the given App to the given ostream.
| os | Stream to which to write. |
| val | Object to serialize. |
os. Definition at line 130 of file app.cpp.
References m_exec_path, m_group_id, m_name, and m_user_id.
| 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):
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 still does not necessarily 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.)
Definition at line 200 of file app.hpp.
Referenced by operator<<(), and ipc::session::Session_server_impl< Session_server_t, Server_session_t >::Session_server_impl().
| util::group_id_t ipc::session::App::m_group_id |
The application must run as this group ID (GID). Files and other shared resources shall have this owner.
Definition at line 206 of file app.hpp.
Referenced by ipc::session::ensure_resource_owner_is_app(), operator<<(), and ipc::session::Session_server_impl< Session_server_t, Server_session_t >::Session_server_impl().
| 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).
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:
set or unordered_set (etc.) of std::string m_names.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.Due to these conventions:
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 iterator-stable-under-insertion, and that brings an annoying host of worries. Indexing by string name is solid by comparison, if a bit slower.
Must begin with an ASCII alphabetical character and otherwise consist of only ASCII alphanumerics (so, notably, no underscores: use camelCase to separate words, per the convention for Shared_name components; see its doc header). While that is partially style-driven, the following is an important guarantee for related Shared_name and fs::path semantics:
Therefore:
So if m_name is "abcDef" one can do things like /some/dir/abcDef/some_file and /some/dir/abcDef.pid/file and /some/dir/prefix.abcDef.3 (file-system example) or "_some_dir_abcDef_moreStuff" (Shared_name example). I.e., m_name can be safely used as a conceptual "token," even when combined with path/name separators and dot-extension naming.
Definition at line 179 of file app.hpp.
Referenced by ipc::session::shm::classic::Session_server< MQ_TYPE_OR_NONE, TRANSMIT_NATIVE_HANDLES, Mdt_payload >::app_shm_ptr(), ipc::session::shm::arena_lend::jemalloc::Session_server< MQ_TYPE_OR_NONE, TRANSMIT_NATIVE_HANDLES, Mdt_payload >::app_shm_ptr(), ipc::session::shm::classic::Session_server< MQ_TYPE_OR_NONE, TRANSMIT_NATIVE_HANDLES, Mdt_payload >::init_app_shm_as_needed(), ipc::session::shm::arena_lend::jemalloc::Session_server< MQ_TYPE_OR_NONE, TRANSMIT_NATIVE_HANDLES, Mdt_payload >::init_app_shm_as_needed(), ipc::transport::struc::shm::rpc::Client_context< Client_session_t >::on_session_hosed(), operator<<(), and ipc::session::Session_server_impl< Session_server_t, Server_session_t >::Session_server_impl().
| util::user_id_t ipc::session::App::m_user_id |
The application must run as this user ID (UID). Files and other shared resources shall have this owner.
Definition at line 203 of file app.hpp.
Referenced by ipc::session::ensure_resource_owner_is_app(), operator<<(), and ipc::session::Session_server_impl< Session_server_t, Server_session_t >::Session_server_impl().