I'm designing a streaming service and am struggling to express it properly using Vertx concepts. Help would be appreciated.
Note that for the sake of the discussion, I've greatly simplified the example such that it only focusses on the streaming aspect. The point is not to find some existing technology that already does this, but rather to find how certain patterns (in this case shared objects with a streaming API) can be expressed with Vertx.
----------------
I want to design a reporting service that can handle a set of reports. To each report data can be appended. Each report can also be read. Since the report can be quite large, I want to design it with a streaming API.
interface Report {
WriteStream<String> append();
ReadStream<String> read(int position);
}
It's important to understand that the report keeps state in memory. For instance, it might stream data that is being appended immediately to open read connections. Since the implementation of it is complex, I want to design it in such a way that, for any given instance of Report, all its logic is always executed within the same EventContext (just like a verticle).
On top of this, I have a reporting service exposed through some REST API.
interface ReportingService {
void append(RoutingContext rc);
void read(RoutingContext rc);
}
The implementation of ReportingService#append should do a lookup to find the report with the name (extracted from the request) and then set up a pipe to stream all the data from the requestContext into the report. Once that pipe has finished, it can close the response context.
The implementation of ReportingService#read is similar. It should do a lookup to find the report with the name (extracted from the request) and then set up a pipe to stream all the data from the report into the response context. Once that pipe has finished, it can close the response context.
---------------
Would it be ok to pass the RoutingContext object through the EventBus (I don't want or need any HA or distribution; local communication within the vertx instance is good enough) and then use it from within a Report verticle?
It feels like cheating and I fear I might break some concurrency contract while doing so.
A similar approach (that feels also like cheating) that would by pass the event bus completely, might look like
// pseudo-code
// it would be problematic for instance to get hold of the report object
report.getContext().runOnContext(() -> report.read(position).pipeTo(rc.response()));
So, what would be the good way to do this?
thanks,
Bert