hmbdc
simplify-high-performance-messaging-programming
Client.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 
4 #include "hmbdc/app/MessageHandler.hpp"
5 #include "hmbdc/pattern/PoolConsumer.hpp"
6 #include "hmbdc/pattern/LockFreeBufferMisc.hpp"
7 #include "hmbdc/Compile.hpp"
8 
9 #include <tuple>
10 
11 namespace hmbdc { namespace app {
12 
13 namespace detail {
15 }
16 
17 using namespace hmbdc::pattern;
18 /**
19  * @brief A Client is one object that participates in message dispatching (receiving end)
20  * @details message is dispatched thru callbacks in the loose
21  * form of void handleMessageCb(Message const& m) or void handleMessageCb(Message& m).
22  * some callbacks have default implementations.
23  * however, all callbacks are overridable to provide desired effects;
24  * When running in a Context, all callbacks (*Cb methods) for a hmbdc Client instance
25  * are garanteed to be called from a single OS thread, ie. no 2 callabacks of an Client
26  * instance are called concurrently, so the Client programmer can assume a
27  * single thread programming model callback-wise.
28  * The above also holds true for timer firing callbacks when a concrete Client deriving
29  * from TimerManager that manages the timers
30  * see @example hmbdc.cpp @example hello-world.cpp for usage
31  *
32  * @tparam CcClient the concrete Client type
33  * @tparam typename ... Messages message types that the Client interested
34  * if the type of JustBytes is declared, a special callback
35  * void handleJustBytesCb(uint16_t tag, uint8_t* bytes) is expected
36  * see ConsoleClient.hpp
37  */
38 template <typename CcClient, typename ... Messages>
39 struct Client
40 : MessageHandler<CcClient, Messages ...>
41 , PoolConsumer {
42  enum {
43  REGISTERED_MESSAGE_SIZE = sizeof...(Messages),
44  };
45 
46  /**
47  * @brief trivial constructor
48  */
50  : hmbdc::pattern::PoolConsumer(REGISTERED_MESSAGE_SIZE) {
51  }
52 
53  /**
54  * @brief called before any messages got dispatched - only once
55  * @details this is the place some preparation code goes to
56  *
57  * @param threadSerialNumber normally the number
58  * indicating which thread is in action, except when REGISTERED_MESSAGE_SIZE == 0
59  * it is another undefined value
60  *
61  */
62  /*virtual*/ void messageDispatchingStartedCb(uint16_t threadSerialNumber) override {
63  //default do nothing
64  };
65 
66  /**
67  * @brief callback called when this Client is taken out of message dispatching
68  * @details after this call the Client is still at hook from the Context point of view
69  * (until droppedCb is called), so don't delete this Client yet or add it back to
70  * the Context. any exception thrown here is ignored,
71  *
72  * @param e the exception that caused the Client to be taken out of message dispatching
73  * e could be thrown by the Client itself in a callback function
74  * to voluntarily take itself out
75  */
76  /*virtual*/ void stoppedCb(std::exception const& e) override {
77  // called when this client is stopped, e.what() might have reason
78  };
79 
80  /**
81  * @brief callback called after the Client is safely taken out of the Context
82  * @details exception thrown here is ignored and return true is assumed
83  * @return if false, this Client is added back to the Context to process messages
84  * otherwise, no more callback. You could even safely "delete this; return true;"
85  */
86  /*virtual*/ bool droppedCb() override {
87  // called when this client is dropped and free to be deleted
88  return true;
89  };
90 
91  /**
92  * @brief this callback is called all the time (frequently)
93  * @details used if the Client needs to do something all the time like
94  * powering another message loop
95  *
96  * @param threadSerialNumber the number
97  * indicating which thread is in action
98  */
99  /*virtual*/ void invokedCb(uint16_t threadSerialNumber) override {
100  // called as frequently as workload allowed
101  }
102 
103  /**
104  * @brief return the name of thread that runs this client, override if necessary
105  * @details this only used when the Client is running in direct mode
106  * @return thread name - default to be hmbdc0, hmbdc1 ...
107  */
108  char const* hmbdcName() const { return nullptr; }
109 
110  /**
111  * @brief an overrideable method.
112  * returns the schedule policy and priority, override if necessary
113  * priority is only used when policy is "SCHED_RR", or "SCHED_FIFO"
114  * @details this is only used when the Client is running in direct mode
115  * supported policy are "SCHED_OTHER"(=nullptr), "SCHED_RR", "SCHED_FIFO"
116  * @return a tuple made of schedule policy and priority, default to be SCHED_OTHER
117  */
118  std::tuple<char const*, int> schedSpec() const {
119  return std::make_tuple<char const*, int>(nullptr, 0);
120  }
121 
122  /**
123  * @brief an overridable method.
124  * client receives events in batches and the max batch size is controllable when running
125  * in direct mode Context. Here is to specify the max size.
126  * @details a message could only be reaching one client when using partition Context. In this
127  * case, reduce the size (reduce the greediness) might be useful
128  * @return the max number of messages when grabbing messages to process
129  */
130  size_t maxBatchMessageCount() const {return std::numeric_limits<size_t>::max();}
131 
132  /**
133  * @brief internal use, don't change or override
134  */
136  BufIt const& end, uint16_t threadSerialNumber) override {
137  CcClient& c = static_cast<CcClient&>(*this);
138  for (;it != end; ++it) {
139  c.MessageHandler<CcClient, Messages ...>::handleMessage(*static_cast<MessageHead*>(*it));
140  }
141  }
142 
143 };
144 
145 }} //hmbdc::app
void handleRangeImpl(BufIt &it, BufIt const &end, uint16_t threadSerialNumber) override
internal use, don&#39;t change or override
Definition: Client.hpp:135
void stoppedCb(std::exception const &e) override
callback called when this Client is taken out of message dispatching
Definition: Client.hpp:76
Client()
trivial constructor
Definition: Client.hpp:49
Definition: GuardedSingleton.hpp:9
std::tuple< char const *, int > schedSpec() const
an overrideable method. returns the schedule policy and priority, override if necessary priority is o...
Definition: Client.hpp:118
char const * hmbdcName() const
return the name of thread that runs this client, override if necessary
Definition: Client.hpp:108
size_t maxBatchMessageCount() const
an overridable method. client receives events in batches and the max batch size is controllable when ...
Definition: Client.hpp:130
void messageDispatchingStartedCb(uint16_t threadSerialNumber) override
called before any messages got dispatched - only once
Definition: Client.hpp:62
void invokedCb(uint16_t threadSerialNumber) override
this callback is called all the time (frequently)
Definition: Client.hpp:99
bool droppedCb() override
callback called after the Client is safely taken out of the Context
Definition: Client.hpp:86
Definition: PoolConsumer.hpp:13
Definition: Client.hpp:39
Definition: Client.hpp:11
Definition: MessageHandler.hpp:38
Definition: LockFreeBufferMisc.hpp:73