cyberRT 发现机制总结

cyberRT 发现机制总结

代码目录

cyber 发现机制的代码都在cyber/service_discovery中,后面我们直接从topology_manager中去分析整个发现机制流程。
以下代码流程中非重要代码都用…替换。

发现机制初始化

bool TopologyManager::Init() {
  if (init_.exchange(true)) {
    return true;
  }
//创建三个类型节点的manager
  node_manager_ = std::make_shared<NodeManager>();
  channel_manager_ = std::make_shared<ChannelManager>();
  service_manager_ = std::make_shared<ServiceManager>();

  CreateParticipant();
//主要是这步处理,对所有类型的manager做初始化
  bool result =
      InitNodeManager() && InitChannelManager() && InitServiceManager();
  if (!result) {
	...
  }

  return true;
}

TopologyManager::Init中主要干三件事,对node、channel、service这三个manager的初始化。init中创建了三个manager,node_manager_ 、channel_manager_ 、service_manager_ ,这三个manager都是继承自Manager。并且三个manager的init函数中做的东西很简单,都是调用了基类的StartDiscovery。我们看下StartDiscovery中的处理:

bool Manager::StartDiscovery(RtpsParticipant* participant) {
  if (participant == nullptr) {
    return false;
  }
  if (is_discovery_started_.exchange(true)) {
    return true;
  }
  //这里创建的是fastRtps的pub和sub
  if (!CreatePublisher(participant) || !CreateSubscriber(participant)) {
    AERROR << "create publisher or subscriber failed.";
    StopDiscovery();
    return false;
  }
  return true;
}

可以看到StartDiscovery中做的处理就是创建出fastRtps的pub和sub,这里我们也可以总结出cyber内部的发现机制通信都是通过fastRtps。这里我理解直接使用fastRtps通信是为了避免自己再去实现trans local的机制。不管是同一机器内的通信,还是不同机器间的通信都使用了fastRtps方式。当然为了性能的极致化,也可以考虑同一机器内发现消息使用共享内存,但是这种的话你就要自己去实现trans local机制。确保晚加入的节点,能收到先加入节点的发现消息。

Topology的join和leave

这里只举例Join。
所有的节点join都是调用的基类方法Manager::Join,可以看下这个函数

bool Manager::Join(const RoleAttributes& attr, RoleType role,
                   bool need_publish) {
  if (is_shutdown_.load()) {
    ADEBUG << "the manager has been shut down.";
    return false;
  }
  RETURN_VAL_IF(!((1 << role) & allowed_role_), false);
  RETURN_VAL_IF(!Check(attr), false);
  ChangeMsg msg;
  Convert(attr, role, OperateType::OPT_JOIN, &msg);
  Dispose(msg);
  if (need_publish) {
    return Publish(msg);
  }
  return true;
}

这里主要看Dispose和Publish这两个。Dispose调用的是各个子类的方法,比如channel拓扑节点变化了,就会调用ChannelManager::Dispose来通过channelManager的节点变化,看下面:

void ChannelManager::Dispose(const ChangeMsg& msg) {
  if (msg.operate_type() == OperateType::OPT_JOIN) {
    DisposeJoin(msg);
  } else {
    DisposeLeave(msg);
  }
  Notify(msg);
}

Dispose会根据这个节点是join还是leave来调用子类的DisposeJoin或者DisposeLeave方法,目的就是更新各个子类manager中保存的节点关系。另外这里还会调用Notify,里面用了QT信号和槽的机制,其实就是触发了一个callback。这个callback是使用方调用TopologyManager中的AddChangeListener设置的一个callback。

再看Publish函数,这函数就是将join或者leave消息通过fastRtps消息发给所有subscribe,让所有sub都去更新拓扑节点关系。可以看下sub收到消息后的处理,收到消息的处理是Manager::OnRemoteChange:

void Manager::OnRemoteChange(const std::string& msg_str) {
  if (is_shutdown_.load()) {
    ADEBUG << "the manager has been shut down.";
    return;
  }

  ChangeMsg msg;
  RETURN_IF(!message::ParseFromString(msg_str, &msg));
  if (IsFromSameProcess(msg)) {
    return;
  }
  RETURN_IF(!Check(msg.role_attr()));
  Dispose(msg);
}

这里的处理也很简单,主要是收到sub拓扑节点变更消息后,触发OnRemoteChange再调用Dispose 来更新自己保存的拓扑关系。

leave这里就不细说了,和join流程差不多。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值