-
Notifications
You must be signed in to change notification settings - Fork 33
Description
I think a folding processing stage would be good. There are a number of use cases that I've come up with, particularly in IoT scenarios.
Let's say you have an IoT device that every few seconds sends the status of a door, ie, whether the door is opened or closed. You want to convert this status to an action, ie, a message should only be sent when the door changes from opened to closed, or vice versa, so that you can then do further processing down the stream without overwhelming your system with these status messages every few seconds. This is what it might look like:
public enum DoorStatus {
Open, Closed;
public DoorAction toAction() {
switch (this) {
case Open: return DoorAction.Opened;
case Closed: return DoorAction.Closed;
}
}
}
public enum DoorAction {
Opened, Closed;
}
@Incoming(provider = WebSocket.class, "door-status")
@Outgoing(provider = Kafka.class, "door-action")
public ProcessorBuilder<DoorStatus, DoorAction> convertDoorStatusToAction() {
return ReactiveStreams.<DoorStatus>builder()
// Fold to keep the last two statuses in an array,
// we use an array because Java doesn't have tuples
.fold(new DoorStatus[0], (prevTwo, next) -> {
if (prevTwo.length == 0) return { next };
else return { next, prevTwo[0] };
})
// Now convert each pair of consecutive statuses to an optional action
.flatMapIterable(pair -> {
// If it's the first one (due to new connection), consider the first one an action
if (pair.length == 1) return List.of(pair[0].toAction());
else if (pair[0] == pair[1]) return List.of();
else return List.of(pair[0].toAction());
});
}Another use case might be that you have a temperature sensor, and you want to output a running average. This can be done in a very similar way to above.
One of the things that makes this not so nice is Java doesn't have a concept of tuples - typically when you do a fold, you want to fold into a tuple of your state, and an event that you want to output, and then a subsequent map will just emit the event and drop the state. But without tuple support in Java, you have to either do like the above, hack it using arrays, or create a new class just to hold your tuple. Of course, there are libraries out there that provide tuples, eg Akka provides Pair, though it's still cumbersome without any sort of syntactic sugaring around it provided by the language.