Skip to content

inheriting an actor #239

Open
Open
@jgornowich

Description

I have tried to create a derived class from a zmqpp::actor to test embedding the routines into a more OO application. Here is s simple test example of what I was thinking was possible.

class Worker : public zmqpp::actor {
 public:
  Worker();

 private:
  std::string _name;
  int _count;

  bool doWork(zmqpp::socket *pipe);
};

Worker::Worker(const std::string &name)
    : actor(std::bind(&Worker::doWork, this, std::placeholders::_1)),
      _name(name) {
};

bool Worker::doWork(zmqpp::socket *pipe) {
  std::cout << "I am starting work" << std::endl;
  zmqpp::message msg;
  zmqpp::signal sig;
  pipe->send(zmqpp::signal::ok);
  bool terminated = false;
  while (!terminated) {
    while (pipe->receive(msg)) {
      if (msg.is_signal()) {
        msg.get(sig, 0);
        if (sig == zmqpp::signal::stop) {
          terminated = true;
          break;
        }
      }
      std::cout << _name << " got message : " << msg.get(0) << std::endl;
      _count++;
    }
  }

  zmqpp::message final_res;
  final_res << std::to_string(_count);
  // send the total count to the parent thread
  pipe->send(final_res);
  return true;
}

int main() {

  std::vector<std::unique_ptr<zmqpp::actor>> actors;

  // create 4 actors
  for (int ii = 0; ii < 4; ii++) {
    std::unique_ptr<zmqpp::actor> ptr(new Worker("worker-" + std::to_string(ii)));
    actors.push_back(std::move(ptr));
  }

  // send 12 times to each actor
  for (int i = 0; i < 12; i++) {
    std::cout << "sending " << i << std::endl;
    std::for_each(actors.begin(), actors.end(), [&](std::unique_ptr<zmqpp::actor> &a) {
      a->pipe()->send("hey" + std::to_string(i));
    });
  }

  // Shutdown each actor and get the results
  std::for_each(actors.begin(), actors.end(), [&](std::unique_ptr<zmqpp::actor> &a) {
      a->pipe()->send(zmqpp::signal::stop);
      zmqpp::message msg;
      a->pipe()->receive(msg);
      std::cout << " parent received" << msg.get(0) << std::endl;
  });

  return 0;
}

I was wondering if this is ok to do this with these actors or if there was some kind of underlying issue with this approach. If there is a better / simpler way to accomplish the same results, I would be curious to hear any suggestions. Also, am I overlooking where a zmqpp::context is required here somewhere or is that only necessary if the ActorRoutine needs to create a zmqpp::socket object?

I understand that there are thread safety concerns with accessing the member variables of this simplistic Worker inside the ActorRoutine here, my question is more related to the zmqpp usage.

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions