hmbdc
simplify-high-performance-messaging-programming
Public Member Functions | List of all members
hmbdc::app::Context< MaxMessageSize, ContextProperties > Class Template Reference

A Context is like a media object that facilitates the communications for the Clients that it is holding. a Client can only be added to (or started within) once to a single Context, undefined behavior otherwise. the communication model is determined by the context_property by default it is in the nature of broadcast fashion within local process indicating by broadcast<> More...

#include <Context.hpp>

Inheritance diagram for hmbdc::app::Context< MaxMessageSize, ContextProperties >:
hmbdc::app::context_detail::ThreadCommBase< MaxMessageSize, ContextProperties... > hmbdc::app::context_detail::context_property_aggregator< ContextProperties... >

Public Member Functions

 Context (uint32_t messageQueueSizePower2Num=MaxMessageSize?20:2, size_t maxPoolClientCount=MaxMessageSize?128:0, size_t maxMessageSizeRuntime=MaxMessageSize)
 ctor for construct local non-ipc Context More...
 
 Context (char const *ipcTransportName, uint32_t messageQueueSizePower2Num=MaxMessageSize?20:0, size_t maxPoolClientCount=MaxMessageSize?128:0, size_t maxMessageSizeRuntime=MaxMessageSize, uint64_t purgerCpuAffinityMask=0xfffffffffffffffful)
 ctor for construct local ipc Context More...
 
 ~Context ()
 dtor More...
 
template<typename Client >
void addToPool (Client &client, uint64_t poolThreadAffinityIn=0xfffffffffffffffful)
 add a client to Context's pool - the Client is run in pool mode More...
 
template<typename Client , typename... Args>
void addToPool (Client &client, uint64_t poolThreadAffinityIn, Args &&...args)
 add a bunch of clients to Context's pool - the Clients are run in pool mode More...
 
size_t clientCountInPool () const
 return the numebr of clients added into pool More...
 
size_t parallelConsumerAlive () const
 how many parallel consummers are started More...
 
template<typename... Args>
void start (uint16_t poolThreadCount, uint64_t poolThreadsCpuAffinityMask, Args &&...args)
 start the context and specify its Pool and direct Clients More...
 
template<typename Client , typename... Args>
std::enable_if<!std::is_integral< Client >::value, void >::type start (Client &c, uint64_t cpuAffinity, Args &&...args)
 start the context (without its Pool) and direct Clients More...
 
void start ()
 tell hmbdc that there is no more direct mode Client to start
 
void stop ()
 stop the message dispatching - asynchronously More...
 
void join ()
 wait until all threads (Pool threads too if apply) of the Context exit More...
 
void setSecondsBetweenPurge (uint32_t s)
 ipc_creator Context runs a StcuClientPurger to purge crashed (or slow, stuck ...) Clients from the ipc transport to make the ipc trasnport healthy (avoiding buffer full). It periodically looks for things to purge. This is to set the period (default is 60 seconds). More...
 
void runPoolThreadOnce (uint16_t threadSerialNumber)
 normally not used until you want to run your own message loop More...
 
template<typename Client >
void runClientThreadOnce (uint16_t threadSerialNumber, Client &c)
 normally not used until you want to run your own message loop More...
 
- Public Member Functions inherited from hmbdc::app::context_detail::ThreadCommBase< MaxMessageSize, ContextProperties... >
enable_if<!std::is_integral< M1 >::value, void >::type send (M0 &&m0, M1 &&m1, Messages &&...msgs)
 try send a batch of messages to the Context or attached ipc Contexts More...
 
void send (ForwardIt begin, size_t n)
 send a range of messages to the Context or attached ipc Contexts More...
 
void send (Message &&m)
 send a message to the Context or attached ipc Contexts More...
 
enable_if<!std::is_integral< M1 >::value, bool >::type trySend (M0 &&m0, M1 &&m1, Messages &&...msgs)
 try to send a batch of message to the Context or attached ipc Contexts More...
 
bool trySend (ForwardIt begin, size_t n)
 try send a range of messages to the Context or attached ipc Contexts More...
 
bool trySend (Message &&m)
 try to send a message to the Context or attached ipc Contexts More...
 
void sendInPlace (Args &&...args)
 send a message to all Clients in the Context or attached ipc Contexts More...
 
Buffer & buffer ()
 accessor - mostly used internally More...
 

Detailed Description

template<size_t MaxMessageSize = 0, typename... ContextProperties>
class hmbdc::app::Context< MaxMessageSize, ContextProperties >

A Context is like a media object that facilitates the communications for the Clients that it is holding. a Client can only be added to (or started within) once to a single Context, undefined behavior otherwise. the communication model is determined by the context_property by default it is in the nature of broadcast fashion within local process indicating by broadcast<>

a broadcast Context contains a thread Pool powered by a number of OS threads. a Client running in such a Context can either run in the pool mode or a direct mode (which means the Client has its own dedicated OS thread) direct mode provides faster responses, and pool mode provides more flexibility. It is recommended that the total number of threads (pool threads + direct threads) not exceeding the number of avalibale cores.

Template Parameters
MaxMessageSizeWhat is the max message size if known at compile time(compile time sized); if the value can only be determined at runtime (run time sized), set this to 0. Things can still work but will lost some compile time checking advantages, see maxMessageSizeRuntime below
ContextPropertiessee context_property namespace
Examples:
chat.cpp, client-server-netmap.cpp, hello-world.cpp, hmbdc.cpp, ipc-market-data-propagate.cpp, mcast-sniff.cpp, rmcast-cp.cpp, and server-cluster.cpp.

Constructor & Destructor Documentation

template<size_t MaxMessageSize = 0, typename... ContextProperties>
hmbdc::app::Context< MaxMessageSize, ContextProperties >::Context ( uint32_t  messageQueueSizePower2Num = MaxMessageSize?20:2,
size_t  maxPoolClientCount = MaxMessageSize?128:0,
size_t  maxMessageSizeRuntime = MaxMessageSize 
)
inline

ctor for construct local non-ipc Context

won't compile if calling it for ipc Context

Parameters
messageQueueSizePower2Numvalue of 10 gives message queue if size of 1024 (messages, not bytes)
maxPoolClientCountup to how many Clients the pool is suppose to support, only used when pool supported in the Context with broadcast property
maxMessageSizeRuntimeif MaxMessageSize set to 0, this value is used
template<size_t MaxMessageSize = 0, typename... ContextProperties>
hmbdc::app::Context< MaxMessageSize, ContextProperties >::Context ( char const *  ipcTransportName,
uint32_t  messageQueueSizePower2Num = MaxMessageSize?20:0,
size_t  maxPoolClientCount = MaxMessageSize?128:0,
size_t  maxMessageSizeRuntime = MaxMessageSize,
uint64_t  purgerCpuAffinityMask = 0xfffffffffffffffful 
)
inline

ctor for construct local ipc Context

won't compile if calling it for local non-ipc Context

Parameters
ipcTransportNamethe id to identify an ipc transport that supports a group of attached together Contexts and their Clients
messageQueueSizePower2Numvalue of 10 gives message queue if size of 1024 (messages, not bytes)
maxPoolClientCountup to how many Clients the pool is suppose to support, only used when pool supported in the Context with broadcast property
maxMessageSizeRuntimeif MaxMessageSize set to 0, this value is used
purgerCpuAffinityMaskwhich cores to run the low profile (sleep mostly) thread in charge of purging crashed Clients. Used only for ipc_creator Contexts.
template<size_t MaxMessageSize = 0, typename... ContextProperties>
hmbdc::app::Context< MaxMessageSize, ContextProperties >::~Context ( )
inline

dtor

if this Context owns ipc transport, notify all attached processes that read from it that this tranport is dead

Member Function Documentation

template<size_t MaxMessageSize = 0, typename... ContextProperties>
template<typename Client >
void hmbdc::app::Context< MaxMessageSize, ContextProperties >::addToPool ( Client client,
uint64_t  poolThreadAffinityIn = 0xfffffffffffffffful 
)
inline

add a client to Context's pool - the Client is run in pool mode

if pool is already started, the client is to get current Messages immediatly

  • might miss older messages. if the pool not started yet, the Client does not get messages or other callbacks until the Pool starts. This function is threadsafe, which means you can call it anywhere in the code
    Template Parameters
    Clientclient type
    Parameters
    clientto be added into the Pool
    poolThreadAffinityInpool is powered by a number of threads (thread in the pool is identified (by a number) in the mask starting from bit 0) it is possible to have a Client to use just some of the threads in the Pool

default to use all.

template<size_t MaxMessageSize = 0, typename... ContextProperties>
template<typename Client , typename... Args>
void hmbdc::app::Context< MaxMessageSize, ContextProperties >::addToPool ( Client client,
uint64_t  poolThreadAffinityIn,
Args &&...  args 
)
inline

add a bunch of clients to Context's pool - the Clients are run in pool mode

if pool is already started, the client is to get current Messages immediatly

  • might miss older messages. if the pool not started yet, the Client does not get messages or other callbacks until the Pool starts. This function is threadsafe, which means you can call it anywhere in the code
    Template Parameters
    Clientclient type
    Parameters
    clientto be added into the Pool
    poolThreadAffinityInpool is powered by a number of threads (thread in the pool is identified (by a number) in the mask starting from bit 0) it is possible to have a Client to use just some of the threads in the Pool

default to use all.

Parameters
argsmore client and poolThreadAffinityIn pairs can follow
template<size_t MaxMessageSize = 0, typename... ContextProperties>
size_t hmbdc::app::Context< MaxMessageSize, ContextProperties >::clientCountInPool ( ) const
inline

return the numebr of clients added into pool

the number could change since the clients could be added in another thread

Returns
client count
template<size_t MaxMessageSize = 0, typename... ContextProperties>
void hmbdc::app::Context< MaxMessageSize, ContextProperties >::join ( )
inline

wait until all threads (Pool threads too if apply) of the Context exit

blocking call

template<size_t MaxMessageSize = 0, typename... ContextProperties>
size_t hmbdc::app::Context< MaxMessageSize, ContextProperties >::parallelConsumerAlive ( ) const
inline

how many parallel consummers are started

the dynamic value could change after the call returns see max_parallel_consumer Context property

Returns
how many parallel consummers are started
template<size_t MaxMessageSize = 0, typename... ContextProperties>
template<typename Client >
void hmbdc::app::Context< MaxMessageSize, ContextProperties >::runClientThreadOnce ( uint16_t  threadSerialNumber,
Client c 
)
inline

normally not used until you want to run your own message loop

call this function frequently to pump hmbdc message loop for a direct mode Client

Parameters
threadSerialNumberindicate which thread is powering the loop
cthe Client
template<size_t MaxMessageSize = 0, typename... ContextProperties>
void hmbdc::app::Context< MaxMessageSize, ContextProperties >::runPoolThreadOnce ( uint16_t  threadSerialNumber)
inline

normally not used until you want to run your own message loop

call this function frequently to pump hmbdc message loop in its pool

Parameters
threadSerialNumberstarting from 0, indicate which thread in the pool is powering the loop
template<size_t MaxMessageSize = 0, typename... ContextProperties>
void hmbdc::app::Context< MaxMessageSize, ContextProperties >::setSecondsBetweenPurge ( uint32_t  s)
inline

ipc_creator Context runs a StcuClientPurger to purge crashed (or slow, stuck ...) Clients from the ipc transport to make the ipc trasnport healthy (avoiding buffer full). It periodically looks for things to purge. This is to set the period (default is 60 seconds).

If some Client are known to take long to process messages, increase it. If you need to remove slow Clients quickly reduce it. Only effective for ipc_creator Context.

Parameters
sseconds
template<size_t MaxMessageSize = 0, typename... ContextProperties>
template<typename... Args>
void hmbdc::app::Context< MaxMessageSize, ContextProperties >::start ( uint16_t  poolThreadCount,
uint64_t  poolThreadsCpuAffinityMask,
Args &&...  args 
)
inline

start the context and specify its Pool and direct Clients

doesn't compile if the Context does not support a Pool. Usage example:

// the following starts the pool powered by 3 threads that are affinitied to
// the lower 8 cores; client0 affinitied to 4th core and client1 affinitied to 5th core
// the last true value inidicates there will be more direct mode clients to start
// and messages are kept for those coming later (this only works for broadcast Context
// not applicable to partition Context).
start(3, 0xfful, client0, 0x8ul, client1, 0x10ul, true);
Template Parameters
typename...Args types
Parameters
poolThreadCounthow many threads to power the Pool, 0 means no pool
poolThreadsCpuAffinityMaskwhich cores, the pool threads to run on
argspairs of direct mode Client and its cpuAffinity; optionally followed by a bool as the last arg (default false), false to indicate there is no more direct mode Client to start. (the bool is not aplicable for IPC Context types) If a cpuAffinity is 0, the Client's affinity rotates to one of the cores in the system.

see in example hmbdc.cpp

//add 40 clients into ctx's threadpool so they could be run later
for (uint16_t i = 0; i < clientCount; ++i) {
clients[i].reset(new MyClient(&ctx, workLoad, clientCount, i));
ctx.addToPool(*clients[i]); //addToPool could also happen after ctx started.
}
//starting context (message dispatching)
ctx.start(3, 0x07ul //3 threads to power the thread pool, and they are running on core 0-2
, mon, 0ul); //mon runs in the direct mode (vs in the pool) and hmdbc picks a core for it
//at this point, all clients are running and listening to messages
//this test count on all messages being dispatched to all clients so they can exit
//when things are all done. in the real world that is hardly the case and the starting
//exiting of clients could be more casual
Examples:
hello-world.cpp.
template<size_t MaxMessageSize = 0, typename... ContextProperties>
template<typename Client , typename... Args>
std::enable_if<!std::is_integral<Client>::value, void>::type hmbdc::app::Context< MaxMessageSize, ContextProperties >::start ( Client c,
uint64_t  cpuAffinity,
Args &&...  args 
)
inline

start the context (without its Pool) and direct Clients

for example

// the following starts client0 affinitied to 4th core and client1 affinitied to 5th core
// AND there is no more direct mode clients to start (since no bool at the end)
start(client0, 0x8ul, client1, 0x10ul);
Template Parameters
typename...Args types
Parameters
argspairs of direct mode Client and its cpuAffinity; optionally followed by a bool as the last arg (default false), false to indicate there is no more direct mode Client to start. (the bool is not aplicable for IPC Context types) If a cpuAffinity is 0, the Client's affinity rotates to one of the cores in the system

see in example server-cluster.cpp

//this the main context, it hosts the network transport engine threads
//and worker threads
WordReverser wr[3];
ctx.start(
//3 worker threads in this hosts
//the buffer type used in the ctx ensures a message goes to
//one and only one of the worker - note transport engines not participating
wr[0], 0x08ul
, wr[1], 0x10ul
, wr[2], 0x20ul
//normally partition Context only holds homogeneous Clients like above
//however, transport engines do not participating messaging dispatching
//safe to run them in any type of Context
, *sengine, 0x40ul
, *rengine, 0x80ul);
template<size_t MaxMessageSize = 0, typename... ContextProperties>
void hmbdc::app::Context< MaxMessageSize, ContextProperties >::stop ( )
inline

stop the message dispatching - asynchronously

asynchronously means not garanteed message dispatching stops immidiately after this non-blocking call


The documentation for this class was generated from the following file: