17#ifndef CYBER_TRANSPORT_TRANSMITTER_HYBRID_TRANSMITTER_H_
18#define CYBER_TRANSPORT_TRANSMITTER_HYBRID_TRANSMITTER_H_
25#include <unordered_map>
31#include "cyber/proto/role_attributes.pb.h"
32#include "cyber/proto/transport_conf.pb.h"
56 std::unordered_map<OptionalMode, TransmitterPtr, std::hash<int>>;
58 std::unordered_map<OptionalMode, std::set<uint64_t>, std::hash<int>>;
61 std::unordered_map<Relation, OptionalMode, std::hash<int>>;
80 void InitTransmitters();
81 void ClearTransmitters();
83 void ClearReceivers();
106 participant_(participant) {
122 std::lock_guard<std::mutex> lock(mutex_);
123 for (
auto& item : transmitters_) {
124 item.second->Enable();
130 std::lock_guard<std::mutex> lock(mutex_);
131 for (
auto& item : transmitters_) {
132 item.second->Disable();
138 auto relation = GetRelation(opposite_attr);
143 uint64_t
id = opposite_attr.
id();
144 std::lock_guard<std::mutex> lock(mutex_);
145 receivers_[mapping_table_[relation]].insert(
id);
146 transmitters_[mapping_table_[relation]]->Enable(opposite_attr);
147 TransmitHistoryMsg(opposite_attr);
152 auto relation = GetRelation(opposite_attr);
157 uint64_t
id = opposite_attr.
id();
158 std::lock_guard<std::mutex> lock(mutex_);
159 receivers_[mapping_table_[relation]].erase(
id);
160 transmitters_[mapping_table_[relation]]->Disable(opposite_attr);
166 std::lock_guard<std::mutex> lock(mutex_);
167 history_->Add(msg, msg_info);
168 for (
auto& item : transmitters_) {
169 item.second->Transmit(msg, msg_info);
177 for (
auto& item : transmitters_) {
178 result = item.second->AcquireMessage(msg);
188 mode_ = std::make_shared<proto::CommunicationMode>();
189 mapping_table_[
SAME_PROC] = mode_->same_proc();
190 mapping_table_[
DIFF_PROC] = mode_->diff_proc();
191 mapping_table_[
DIFF_HOST] = mode_->diff_host();
195void HybridTransmitter<M>::ObtainConfig() {
196 auto& global_conf = common::GlobalData::Instance()->Config();
197 if (!global_conf.has_transport_conf()) {
200 if (!global_conf.transport_conf().has_communication_mode()) {
203 mode_->CopyFrom(global_conf.transport_conf().communication_mode());
205 mapping_table_[
SAME_PROC] = mode_->same_proc();
206 mapping_table_[
DIFF_PROC] = mode_->diff_proc();
207 mapping_table_[
DIFF_HOST] = mode_->diff_host();
211void HybridTransmitter<M>::InitHistory() {
212 HistoryAttributes history_attr(this->attr_.qos_profile().history(),
213 this->attr_.qos_profile().depth());
214 history_ = std::make_shared<History<M>>(history_attr);
215 if (this->attr_.qos_profile().durability() ==
216 QosDurabilityPolicy::DURABILITY_TRANSIENT_LOCAL) {
222void HybridTransmitter<M>::InitTransmitters() {
223 std::set<OptionalMode> modes;
224 modes.insert(mode_->same_proc());
225 modes.insert(mode_->diff_proc());
226 modes.insert(mode_->diff_host());
227 for (
auto& mode : modes) {
229 case OptionalMode::INTRA:
230 transmitters_[mode] =
231 std::make_shared<IntraTransmitter<M>>(this->attr_);
233 case OptionalMode::SHM:
234 transmitters_[mode] = std::make_shared<ShmTransmitter<M>>(this->attr_);
237 transmitters_[mode] =
238 std::make_shared<RtpsTransmitter<M>>(this->attr_, participant_);
245void HybridTransmitter<M>::ClearTransmitters() {
246 for (
auto& item : transmitters_) {
247 item.second->Disable();
249 transmitters_.clear();
253void HybridTransmitter<M>::InitReceivers() {
254 std::set<uint64_t> empty;
255 for (
auto& item : transmitters_) {
256 receivers_[item.first] = empty;
261void HybridTransmitter<M>::ClearReceivers() {
266void HybridTransmitter<M>::TransmitHistoryMsg(
267 const RoleAttributes& opposite_attr) {
269 if (this->attr_.qos_profile().durability() !=
270 QosDurabilityPolicy::DURABILITY_TRANSIENT_LOCAL) {
275 std::vector<typename History<M>::CachedMessage> unsent_msgs;
276 history_->GetCachedMessage(&unsent_msgs);
277 if (unsent_msgs.empty()) {
281 auto attr = opposite_attr;
282 cyber::Async(&HybridTransmitter<M>::ThreadFunc,
this, attr, unsent_msgs);
286void HybridTransmitter<M>::ThreadFunc(
287 const RoleAttributes& opposite_attr,
288 const std::vector<
typename History<M>::CachedMessage>& msgs) {
290 RoleAttributes new_attr;
291 new_attr.CopyFrom(this->attr_);
292 std::string new_channel_name =
293 std::to_string(this->attr_.id()) + std::to_string(opposite_attr.id());
295 new_attr.set_channel_name(new_channel_name);
296 new_attr.set_channel_id(channel_id);
297 auto new_transmitter =
298 std::make_shared<RtpsTransmitter<M>>(new_attr, participant_);
299 new_transmitter->Enable();
301 for (
auto& item : msgs) {
302 new_transmitter->Transmit(item.msg, item.msg_info);
305 new_transmitter->Disable();
306 ADEBUG <<
"trans threadfunc exit.";
310Relation HybridTransmitter<M>::GetRelation(
311 const RoleAttributes& opposite_attr) {
312 if (opposite_attr.channel_name() != this->attr_.channel_name()) {
315 if (opposite_attr.host_ip() != this->attr_.host_ip()) {
318 if (opposite_attr.process_id() != this->attr_.process_id()) {
static uint64_t RegisterChannel(const std::string &channel)
std::unordered_map< OptionalMode, std::set< uint64_t >, std::hash< int > > ReceiverMap
std::unordered_map< OptionalMode, TransmitterPtr, std::hash< int > > TransmitterMap
std::unordered_map< Relation, OptionalMode, std::hash< int > > MappingTable
bool Transmit(const MessagePtr &msg, const MessageInfo &msg_info) override
std::shared_ptr< Transmitter< M > > TransmitterPtr
HybridTransmitter(const RoleAttributes &attr, const ParticipantPtr &participant)
virtual ~HybridTransmitter()
std::shared_ptr< History< M > > HistoryPtr
std::shared_ptr< M > MessagePtr
std::shared_ptr< proto::CommunicationMode > CommunicationModePtr
bool AcquireMessage(std::shared_ptr< M > &msg)
std::shared_ptr< Participant > ParticipantPtr
Relation
Describe relation between nodes, writers/readers...