Skip to content

Fold processing stage #66

@jroper

Description

@jroper

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions