Skip to content

Commit e921a63

Browse files
committed
Added tutorial25 README.
1 parent 53f6447 commit e921a63

File tree

3 files changed

+131
-3
lines changed

3 files changed

+131
-3
lines changed

tutorials/tutorial24/src/ServerSession.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include "tutorial24/frame/Frame.h"
77
#include "tutorial24/input/ServerInputMessages.h"
88
#include "tutorial24/options/ServerDefaultOptions.h"
9-
#include "tutorial24/options/DataViewDefaultOptions.h"
109
#include "Session.h"
1110

1211
namespace cc_tutorial

tutorials/tutorial25/README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,135 @@
11
# Tutorial 25
22
Dealing with big protocols.
33

4+
Most of the binary communication protocols use numeric message ID information reported in the
5+
message frame. The [CommsDSL](https://github.com/commschamp/CommsDSL-Specification) specification
6+
provides [<id>](https://commschamp.github.io/commsdsl_spec/#frames-id) framing layer for this purpose, while the generated code uses
7+
[comms::protocol::MsgIdLayer](https://commschamp.github.io/comms_doc/classcomms_1_1protocol_1_1MsgIdLayer.html) class
8+
to implement the required functionality. During the **read** operation the
9+
[comms::protocol::MsgIdLayer](https://commschamp.github.io/comms_doc/classcomms_1_1protocol_1_1MsgIdLayer.html) class
10+
is responsible to provide the functionality for reading the message ID and create appropriate message object before forwarding
11+
the request to the next framing layer. The
12+
default mapping of the numeric message ID to the actual message type is implemented using
13+
[comms::MsgFactory](https://commschamp.github.io/comms_doc/classcomms_1_1MsgFactory.html) class.
14+
The latter receives a `tuple` of all the message classes it is expected to support as its second template parameter
15+
and uses multiple meta-programming techniques to analyze the provided messages at **compile-time** and
16+
create proper mapping of numeric message IDs to their respective actual types. Such compile time analysis may incur
17+
a significant burden on compilation time as well as memory consumption of the compiler. Depending on the
18+
development machine characteristics, the compilation performance issues may get noticeable when number of the
19+
messages approaches 30 - 50. In some specific cases (like small RAM and/or compiler being 32 bit application)
20+
the compilation may report an error due to being out of heap space.
421

22+
To mitigate this problem / annoyance the **v6.1** of the **commsdsl2comms** code generator added extra `switch`
23+
based message factories in the [<protocol_namespace>/factory](include/tutorial25/factory) folder.
24+
25+
- [<protocol_namespace>::factory::AllMessagesDynMemMsgFactory](include/tutorial25/factory/AllMessagesDynMemMsgFactory.h) class -
26+
a factory for all the messages of the protocol.
27+
- [<protocol_namespace>::factory::ClientInputMessagesDynMemMsgFactory](include/tutorial25/factory/ClientInputMessagesDynMemMsgFactory.h) class -
28+
a factory for the client input messages of the protocol.
29+
- [<protocol_namespace>::factory::ServerInputMessagesDynMemMsgFactory](include/tutorial25/factory/ServerInputMessagesDynMemMsgFactory.h) class -
30+
a factory for the server input messages of the protocol.
31+
32+
The **DynMem** part of the name implies dynamic memory allocation.
33+
34+
Note that in this tutorial **sender** property hasn't been used, i.e. all the messages are sent both ways. It means that all the message factories
35+
mentioned above contain the same code. For the cases when uni-directional messages are present they'll differ.
36+
37+
The [comms::protocol::MsgIdLayer](https://commschamp.github.io/comms_doc/classcomms_1_1protocol_1_1MsgIdLayer.html) layer provided by the
38+
[COMMS Library](https://github.com/commschamp/comms) allows replacing the default message factory
39+
([comms::MsgFactory](https://commschamp.github.io/comms_doc/classcomms_1_1MsgFactory.html))
40+
using the **comms::option::app::MsgFactory** or **comms::option::app::MsgFactoryTempl** application specific customization options.
41+
42+
The **v6.1** of the **commsdsl2comms** code generator also generates extra protocol options that can be used to apply the relevant
43+
option to the [comms::protocol::MsgIdLayer](https://commschamp.github.io/comms_doc/classcomms_1_1protocol_1_1MsgIdLayer.html) class:
44+
45+
- [<protocol_namespace>::optoins::AllMessagesDynMemMsgFactoryDefaultOptions](include/tutorial25/options/AllMessagesDynMemMsgFactoryDefaultOptions.h) - the options forcing usage
46+
of the [<protocol_namespace>::factory::AllMessagesDynMemMsgFactory](include/tutorial25/factory/AllMessagesDynMemMsgFactory.h).
47+
- [<protocol_namespace>::optoins::ClientInputMessagesDynMemMsgFactoryDefaultOptions](include/tutorial25/options/ClientInputMessagesDynMemMsgFactoryDefaultOptions.h) -
48+
the options forcing usage of the [<protocol_namespace>::factory::ClientInputMessagesDynMemMsgFactory](include/tutorial25/factory/ClientInputMessagesDynMemMsgFactory.h).
49+
- [<protocol_namespace>::optoins::ServerInputMessagesDynMemMsgFactoryDefaultOptions](include/tutorial25/options/ServerInputMessagesDynMemMsgFactoryDefaultOptions.h) -
50+
the options forcing usage of the [<protocol_namespace>::factory::ServerInputMessagesDynMemMsgFactory](include/tutorial25/factory/ServerInputMessagesDynMemMsgFactory.h).
51+
52+
Let's take a look how the protocol options above can be used to force usage of the more efficient message factories.
53+
54+
The [ServerSession](src/ServerSession.h) defines its protocol options like this:
55+
```cpp
56+
using ServerProtocolOptions =
57+
ServerInputMessagesDynMemMsgFactoryDefaultOptionsT<
58+
tutorial25::options::ServerDefaultOptions
59+
>;
60+
```
61+
62+
The definition used by the [ClientSession](src/ClientSession.h) is very similar:
63+
```cpp
64+
using ClientProtocolOptions =
65+
tutorial25::options::ClientInputMessagesDynMemMsgFactoryDefaultOptionsT<
66+
tutorial25::options::ClientDefaultOptions
67+
>;
68+
```
69+
70+
When it comes to aliasing of the message types, the **v6.1** of the commsdsl2comms code generator added
71+
convenience macros to the definitions of the input messages:
72+
73+
- **&lt;PROT_NS&gt;_ALIASES_FOR_ALL_MESSAGES** and **&lt;PROT_NS&gt;_ALIASES_FOR_ALL_MESSAGES_DEFULT_OPTIONS** in
74+
[&lt;protocol_namespace&gt;/input/AllMessages.h](include/tutorial25/input/AllMessages.h)
75+
- **&lt;PROT_NS&gt;_ALIASES_FOR_CLIENT_INPUT_MESSAGES** and **&lt;PROT_NS&gt;_ALIASES_FOR_CLIENT_INPUT_MESSAGES_DEFULT_OPTIONS** in
76+
[&lt;protocol_namespace&gt;/input/ClientInputMessages.h](include/tutorial25/input/ClientInputMessages.h)
77+
- **&lt;PROT_NS&gt;_ALIASES_FOR_SERVER_INPUT_MESSAGES** and **&lt;PROT_NS&gt;_ALIASES_FOR_SERVER_INPUT_MESSAGES_DEFULT_OPTIONS** in
78+
[&lt;protocol_namespace&gt;/input/ServerInputMessages.h](include/tutorial25/input/ServerInputMessages.h)
79+
80+
Please take a look at the definition:
81+
```cpp
82+
/// @brief Create type aliases for the all messages of the protocol.
83+
/// @param prefix_ Prefix of the alias message type.
84+
/// @param suffix_ Suffix of the alias message type.
85+
/// @param interface_ Type of the common message interface.
86+
/// @param opts_ Type of the used protocol definition options.
87+
#define TUTORIAL25_ALIASES_FOR_ALL_MESSAGES(prefix_, suffix_, interface_, opts_) \
88+
using prefix_ ## Msg1 ## suffix_ = tutorial25::message::Msg1<interface_, opts_>; \
89+
using prefix_ ## Msg2 ## suffix_ = tutorial25::message::Msg2<interface_, opts_>; \
90+
...
91+
```
92+
93+
The [ClientSession](src/ClientSession.h) uses the **TUTORIAL25_ALIASES_FOR_ALL_MESSAGES** macro to alias all message types:
94+
```cpp
95+
TUTORIAL25_ALIASES_FOR_ALL_MESSAGES(,,Message,ClientProtocolOptions);
96+
```
97+
98+
Please note the empty `prefix_` and `suffix_` parameters.
99+
100+
It is equivalent of having the following alias types defined:
101+
```cpp
102+
using Msg1 = tutorial25::message::Msg1<Message, ClientProtocolOptions>;
103+
using Msg2 = tutorial25::message::Msg2<Message, ClientProtocolOptions>;
104+
using Msg3 = tutorial25::message::Msg3<Message, ClientProtocolOptions>;
105+
...
106+
```
107+
108+
These alias types are used when sending messages to the **server**:
109+
```cpp
110+
void ClientSession::sendMsg1()
111+
{
112+
Msg1 msg;
113+
sendMessage(msg); // Should get received and echoed back
114+
}
115+
116+
void ClientSession::sendMsg2()
117+
{
118+
Msg2 msg;
119+
sendMessage(msg); // Should get received and echoed back
120+
}
121+
122+
...
123+
```
5124

6125
## Summary
7126

127+
- As the number of messages in the protocol grow, the burden on the compilation time and memory consumption can grow exponentially.
128+
- When number of the messages exceeds 20-30 messages, it is recommended to use more optimized generated message factories.
129+
- The message factory classes reside in the **&lt;protocol_namespace&gt;/factory** folder.
130+
- The **&lt;protocol_namespace&gt;/options** folder will also contain new relevant option classes which can be used to
131+
force usage of the new factories.
132+
- The files containing definitions of relevant input messages in the **&lt;protocol_namespace&gt;/input** folder also contain
133+
definition of the macros helping with message type aliasing.
8134

9135
[Read Previous Tutorial](../tutorial24) &lt;-----------------------

tutorials/tutorial25/src/ServerSession.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "tutorial25/frame/Frame.h"
77
#include "tutorial25/input/ServerInputMessages.h"
88
#include "tutorial25/options/ServerDefaultOptions.h"
9-
#include "tutorial25/options/DataViewDefaultOptions.h"
9+
#include "tutorial25/options/ServerInputMessagesDynMemMsgFactoryDefaultOptions.h"
1010
#include "Session.h"
1111

1212
namespace cc_tutorial
@@ -29,7 +29,10 @@ class ServerSession : public Session
2929
comms::option::app::Handler<ServerSession> // Polymorphic dispatch
3030
>;
3131

32-
using ServerProtocolOptions = tutorial25::options::ServerDefaultOptions;
32+
using ServerProtocolOptions =
33+
ServerInputMessagesDynMemMsgFactoryDefaultOptionsT<
34+
tutorial25::options::ServerDefaultOptions
35+
>;
3336

3437
// Handle all the received messages
3538
void handle(Message& msg);

0 commit comments

Comments
 (0)