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/Compile.hpp"
6 
7 #include <tuple>
8 
9 namespace hmbdc { namespace app {
10 /**
11  * @class single_thread_powered_client
12  * @brief a trait class, if a Client can only run on a single specific thread in Pool,
13  * derive the Client from it, hmbdc will check to ensure that is the case
14  */
16 
17 /**
18  * @class Client<>
19  * @brief A Client represents a thread of execution/a task. The execution is managed by a Context.
20  * a Client object could participate in message dispatching as the receiver of specifed message types
21  * @details message is dispatched thru callbacks in the loose
22  * form of void handleMessageCb(Message const& m) or void handleMessageCb(Message& m).
23  * some callbacks have default implementations.
24  * however, all callbacks are overridable to provide desired effects;
25  * When running in a Context, all callbacks (*Cb methods) for a hmbdc Client instance
26  * are garanteed to be called from a single OS thread, ie. no 2 callabacks of an Client
27  * instance are called concurrently, so the Client programmer can assume a
28  * single thread programming model callback-wise.
29  * The above also holds true for timer firing callbacks when a concrete Client deriving
30  * from TimerManager that manages the timers
31  *
32  * See in example hmbdc.cpp @snippet hmbdc.cpp write a Client
33  *
34  * @tparam CcClient the concrete Client type
35  * @tparam typename ... Messages message types that the Client interested
36  * if the type of JustBytes is declared, a special callback
37  *
38  * @code
39  * void handleJustBytesCb(uint16_t tag, uint8_t* bytes){...}
40  * @endcode
41  * is expected
42  * see ConsoleClient.hpp
43  */
44 template <typename CcClient, typename ... Messages>
45 struct Client
46 : MessageHandler<CcClient, Messages ...> {
47  enum {
48  REGISTERED_MESSAGE_SIZE = sizeof...(Messages),
49  };
50  using Interests = std::tuple<Messages ...>;
51 
52  /**
53  * @brief return the name of thread that runs this client, override if necessary
54  * @details this only used when the Client is running in direct mode
55  * @return thread name - default to be hmbdc0, hmbdc1 ...
56  */
57  char const* hmbdcName() const { return nullptr; }
58 
59  /**
60  * @brief an overrideable method.
61  * returns the schedule policy and priority, override if necessary
62  * priority is only used when policy is "SCHED_RR", or "SCHED_FIFO"
63  * @details this is only used when the Client is running in direct mode
64  * supported policy are "SCHED_OTHER"(=nullptr), "SCHED_RR", "SCHED_FIFO"
65  * @return a tuple made of schedule policy and priority, default to be SCHED_OTHER
66  */
67  std::tuple<char const*, int> schedSpec() const {
68  return std::make_tuple<char const*, int>(nullptr, 0);
69  }
70 
71  /**
72  * @brief an overridable method.
73  * client receives events in batches and the max batch size is controllable when running
74  * in direct mode Context. Here is to specify the max size.
75  * @details a message could only be reaching one client when using partition Context. In this
76  * case, reduce the size (reduce the greediness) might be useful
77  * @return the max number of messages when grabbing messages to process
78  */
79  size_t maxBatchMessageCount() const {return std::numeric_limits<size_t>::max();}
80 
81 
82  /**
83  * @brief called before any messages got dispatched - only once
84  * @details this is the place some preparation code goes to
85  *
86  * @param threadSerialNumber normally the number
87  * indicating which thread is in action, except when REGISTERED_MESSAGE_SIZE == 0
88  * it is another undefined value
89  *
90  */
91  virtual void messageDispatchingStartedCb(uint16_t threadSerialNumber) {
92  //default do nothing
93  };
94 
95  /**
96  * @brief callback called when this Client is taken out of message dispatching
97  * @details after this call the Client is still at hook from the Context point of view
98  * (until droppedCb is called), so don't delete this Client yet or add it back to
99  * the Context. any exception thrown here is ignored,
100  *
101  * @param e the exception that caused the Client to be taken out of message dispatching
102  * e could be thrown by the Client itself in a callback function
103  * to voluntarily take itself out
104  */
105  virtual void stoppedCb(std::exception const& e) {
106  // called when this client is stopped, e.what() might have reason
107  };
108 
109  /**
110  * @brief callback called after the Client is safely taken out of the Context
111  * @details exception thrown here is ignored and return true is assumed
112  * @return if false, this Client is added back to the Context to process messages
113  * otherwise, no more callback. You could even safely "delete this; return true;"
114  */
115  virtual bool droppedCb() {
116  // called when this client is dropped and free to be deleted
117  return true;
118  };
119 
120  /**
121  * @brief this callback is called all the time (frequently) - the exact timing is
122  * after a batch of messages are dispatched. After this call returns, the previously
123  * dispatched message's addresses are no longer valid, which means if you cache the
124  * event addresses in the previous handleMessageCb()s, you cannot use those after
125  * the return of the next invokeCb function.
126  * @details you can collectively process the messages received/cached so far here, or
127  * do something needs to be done all the time like powering another message loop
128  *
129  * @param threadSerialNumber the number
130  * indicating which thread is in action
131  */
132  virtual void invokedCb(uint16_t threadSerialNumber) {
133  // called as frequently as workload allowed
134  }
135 
136  /**
137  * @brief trivial
138  */
139  virtual ~Client(){}
140 
141  /**
142  * @brief internal use, don't change or override
143  */
144  void stopped(std::exception const&e) noexcept {
145  try {
146  stoppedCb(e);
147  } catch (...) {}
148  }
149 
150  bool dropped() noexcept {
151  bool res = true;
152  try {
153  res = droppedCb();
154  } catch (...) {}
155  return res;
156  }
157 
158  template <typename Iterator>
159  void handleRangeImpl(Iterator it,
160  Iterator end, uint16_t threadId) {
161  CcClient& c = static_cast<CcClient&>(*this);
162  for (;it != end; ++it) {
163  c.MessageHandler<CcClient, Messages ...>::handleMessage(*static_cast<MessageHead*>(*it));
164  }
165  }
166 };
167 
168 }} //hmbdc::app
char const * hmbdcName() const
return the name of thread that runs this client, override if necessary
Definition: Client.hpp:57
virtual ~Client()
trivial
Definition: Client.hpp:139
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:67
virtual bool droppedCb()
callback called after the Client is safely taken out of the Context
Definition: Client.hpp:115
virtual void invokedCb(uint16_t threadSerialNumber)
this callback is called all the time (frequently) - the exact timing is after a batch of messages are...
Definition: Client.hpp:132
void stopped(std::exception const &e) noexcept
internal use, don&#39;t change or override
Definition: Client.hpp:144
size_t maxBatchMessageCount() const
an overridable method. client receives events in batches and the max batch size is controllable when ...
Definition: Client.hpp:79
virtual void stoppedCb(std::exception const &e)
callback called when this Client is taken out of message dispatching
Definition: Client.hpp:105
virtual void messageDispatchingStartedCb(uint16_t threadSerialNumber)
called before any messages got dispatched - only once
Definition: Client.hpp:91
a trait class, if a Client can only run on a single specific thread in Pool, derive the Client from i...
Definition: Client.hpp:15
A Client represents a thread of execution/a task. The execution is managed by a Context. a Client object could participate in message dispatching as the receiver of specifed message types.
Definition: Client.hpp:45
a std tuple holding messages types it can dispatch
Definition: BlockingContext.hpp:157
Definition: Base.hpp:12
Definition: MessageHandler.hpp:39