hmbdc
simplify-high-performance-messaging-programming
ClientWithStash.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 
4 #include "hmbdc/app/Client.hpp"
5 #include "hmbdc/app/Message.hpp"
6 
7 #include <deque>
8 
9 namespace hmbdc { namespace app {
10 /**
11  * @class ClientWithStash<>
12  * @brief It behaves like Client, with the extra capability of storing messages received and processing
13  * them later - it is used when the user wants to process messages in a specific order other than
14  * FIFO. If a message is deemed to come too early, just stash it and move on (to
15  * the next message). The stashed messages will be delivered later at the user's choice - see the added
16  * stash and openStash functions. The stash mechanism can enforce any particular order of message
17  * processing regarless of the order of message being sent.
18  *
19  * @tparam CcClient the concrete Client type
20  * @tparam MaxStashedMessageSizeIn byte size of the max message that will need to be stashed,
21  * use 0 to auto-set to hold the max interested message
22  * @tparam typename ... Messages message types that the Client interested
23  */
24 template <typename CcClient, size_t MaxStashedMessageSizeIn, MessageC ... Messages>
26 : Client<CcClient, Messages...> {
27  using Base = Client<CcClient, Messages...>;
28  using Interests = typename Base::Interests;
29 
30  enum {
31  MaxStashedMessageSize = MaxStashedMessageSizeIn
32  ?MaxStashedMessageSizeIn
34  };
35 
36 protected:
37 /**
38  * @brief stash a message that will be delivered later to the same callback
39  * @details when the Client decide a message is not ready to be handled now but is needed later,
40  * it calls this message to stash it, see also openStash()
41  *
42  * @param message the message to be stashed
43  */
44  template <MessageC Message>
45  void stash(Message const& message) {
46  static_assert(index_in_tuple<Message, std::tuple<Messages...>>::value != sizeof...(Messages)
47  , "cannot stash uninterested message");
48  stash_.push_back(typename decltype(stash_)::value_type{});
49  new (stash_.back().data()) MessageWrap<Message>(message);
50  }
51 
52 
53 /**
54  * @brief release the stashed messages - after this call is returned, the callbacks of
55  * the stahsed message will be invoked with the stashed messages
56  * @details it is fine to stash more / new messages even in the above callbacks invoked
57  * due to stashed messages
58  */
59  void openStash() {
60  stashOpenCount_ = stash_.size();
61  }
62 
63 private:
64  void consumeStash() {
65  CcClient& c = static_cast<CcClient&>(*this);
66  while (hmbdc_unlikely(stashOpenCount_)) {
67  auto m = (MessageHead*)stash_.front().data();
69  stash_.pop_front();
70  stashOpenCount_--;
71  }
72  }
73  size_t stashOpenCount_ = 0;
74  std::deque<std::array<char, MaxStashedMessageSize + sizeof(MessageHead)>> stash_;
75 
76 public:
77 /**
78  * @brief do not touch - internal use
79  */
80  template <typename Iterator>
81  size_t handleRangeImpl(Iterator it, Iterator end, uint16_t threadId) {
82  auto res = Base::handleRangeImpl(it, end, threadId);
83  consumeStash();
84  return res;
85  }
86 };
87 
88 }} //hmbdc::app
Definition: MetaUtils.hpp:48
Definition: MessageDispacher.hpp:184
void openStash()
release the stashed messages - after this call is returned, the callbacks of the stahsed message will...
Definition: ClientWithStash.hpp:59
Definition: Message.hpp:212
size_t handleRangeImpl(Iterator it, Iterator end, uint16_t threadId)
do not touch - internal use
Definition: ClientWithStash.hpp:81
Definition: Message.hpp:263
Definition: MetaUtils.hpp:100
It behaves like Client, with the extra capability of storing messages received and processing them la...
Definition: ClientWithStash.hpp:25
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:122
a std tuple holding messages types it can dispatch
Definition: BlockingContext.hpp:206
Definition: Base.hpp:12
void stash(Message const &message)
stash a message that will be delivered later to the same callback
Definition: ClientWithStash.hpp:45