reader.h

6 篇文章 0 订阅
6 篇文章 0 订阅

Init

template <typename MessageT>
bool Reader<MessageT>::Init() {
  if (init_.exchange(true)) {
    return true;
  }
  std::function<void(const std::shared_ptr<MessageT>&)> func;
  if (reader_func_ != nullptr) {
    func = [this](const std::shared_ptr<MessageT>& msg) {
      this->Enqueue(msg);
      this->reader_func_(msg);
    };
  } else {
    func = [this](const std::shared_ptr<MessageT>& msg) { this->Enqueue(msg); };
  }
  auto sched = scheduler::Instance();
  croutine_name_ = role_attr_.node_name() + "_" + role_attr_.channel_name();
  auto dv = std::make_shared<data::DataVisitor<MessageT>>(
      role_attr_.channel_id(), pending_queue_size_);
  // Using factory to wrap templates.
  croutine::RoutineFactory factory =
      croutine::CreateRoutineFactory<MessageT>(std::move(func), dv);
  if (!sched->CreateTask(factory, croutine_name_)) {
    AERROR << "Create Task Failed!";
    init_.store(false);
    return false;
  }

  receiver_ = ReceiverManager<MessageT>::Instance()->GetReceiver(role_attr_);
  this->role_attr_.set_id(receiver_->id().HashValue());
  channel_manager_ =
      service_discovery::TopologyManager::Instance()->channel_manager();
  JoinTheTopology();

  return true;
}
  1. 原子交换初始化标志:
    • 首先,它尝试通过init_.exchange(true)设置初始化标志为true。如果这个操作成功(即之前未被初始化),则直接返回true,表示已经初始化过了或者同时有其他线程正在初始化。
  1. 定义消息处理函数:
    • 根据成员变量reader_func_是否为空,定义了两种消息处理逻辑。如果不为空,意味着用户自定义了一个消息处理回调,因此创建一个lambda函数,该函数先将消息入队到内部队列,然后调用用户提供的回调处理消息。如果为空,则只执行入队操作。
  1. 创建数据访问器和协程工厂:
    • 实例化一个data::DataVisitor对象,它负责管理指定大小的消息缓冲队列。
    • 使用croutine::CreateRoutineFactory创建一个协程工厂,传入前面定义的lambda作为消息处理函数和刚创建的数据访问器。这个工厂是为了能够创建处理特定类型MessageT消息的协程。
  1. 在调度器中创建任务:
    • 获取全局的调度器实例,并尝试使用上面创建的协程工厂创建一个任务,任务名称由节点名和通道名组合而成。如果创建失败,则记录错误日志,回滚初始化标志,并返回false。
  1. 注册接收器和设置角色属性:
    • 从一个管理接收器的单例类中获取与当前角色属性(role_attr_)匹配的接收器实例。
    • 设置角色的ID为获取到的接收器ID的哈希值。
  1. 加入拓扑结构:
    • 获取服务发现模块中的通道管理器实例,这通常涉及到系统中各组件如何相互通信的管理。
    • 调用JoinTheTopology()方法(未在代码片段中定义),可能涉及向系统拓扑中注册当前读取器,以便其他组件可以发现并与其通信。

JoinTheTopology

oid Reader<MessageT>::JoinTheTopology() {
  // add listener
  change_conn_ = channel_manager_->AddChangeListener(std::bind(
      &Reader<MessageT>::OnChannelChange, this, std::placeholders::_1));

  // get peer writers
  const std::string& channel_name = this->role_attr_.channel_name();
  std::vector<proto::RoleAttributes> writers;
  channel_manager_->GetWritersOfChannel(channel_name, &writers);
  for (auto& writer : writers) {
    receiver_->Enable(writer);
  }
  channel_manager_->Join(this->role_attr_, proto::RoleType::ROLE_READER,
                         message::HasSerializer<MessageT>::value);
}

从上面可以看出,JoinTheTopology函数中,同样的注册了参与者发现的回调函数,然后获取channelname,然后根据channelname获取名字,

template <typename MessageT>
void Reader<MessageT>::OnChannelChange(const proto::ChangeMsg& change_msg) {
  if (change_msg.role_type() != proto::RoleType::ROLE_WRITER) {
    return;
  }

  auto& writer_attr = change_msg.role_attr();
  if (writer_attr.channel_name() != this->role_attr_.channel_name()) {
    return;
  }

  auto operate_type = change_msg.operate_type();
  if (operate_type == proto::OperateType::OPT_JOIN) {
    receiver_->Enable(writer_attr);
  } else {
    receiver_->Disable(writer_attr);
  }
}
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lobmo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值