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.