I've prototyped something that sounds a little similar to this and it
works well. I have a controller actor running on one node that maintains
a list of pending work. Worker actors are started on other nodes and
connect to the controller actor to request work which they then process.
The worker actors are just thin wrappers around instances of a large,
legacy C++ application which is in effect a batch process. The worker
nodes create a worker actor for each instance of the legacy app, plus
there is a shared localhost-only Akka HTTP server actor to provide a
protobuf endpoint for the C++ app instances on the worker node to talk
to. The C++ app has been modified to use libcurl & protobuf to connect
to the localhost HTTP server to request work details and provide
completion information which is 'proxied' back by the worker actors to
the controller actor on the controller node.
All the external communication is done with protobuf, both between the
akka actors on the master and worker nodes and between the worker actors
and the legacy C++ app, via the localhost HTTP actor. I've used akka
remoting for the cross-node control rather than akka cluster as if the
controller node dies there is nothing further that can be done anyway
and the worker actors just kill any running C++ app instances and exit.
Workers can be added dynamically and will be issued pending work and if
they die the controller will reschedule the work they were doing to
another worker.
This all works nicely and protobuf integrates well into Akka HTTP, with
the addition of a tiny amount of glue code to to the protobuf
marshalling for akka HTTP - see
https://github.com/scalapb/ScalaPB/issues/247 for the details. With that
in place, the routing logic for processing looks similar to this
outline, where JobFinishedMsg is a protobuf message:
path("job_finished") {
post {
entity(as[JobFinishedMsg])(msg => {
log.debug("received message {}",
msg.id)
???
}
}
}
--
Alan Burlison
--