All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.pincette.mongo.streams.Probe Maven / Gradle / Ivy

The newest version!
package net.pincette.mongo.streams;

import static java.time.Duration.between;
import static java.time.Instant.now;
import static java.time.temporal.ChronoUnit.MINUTES;
import static java.util.Optional.empty;
import static net.pincette.json.JsonUtil.createObjectBuilder;
import static net.pincette.json.JsonUtil.isObject;
import static net.pincette.rs.Async.mapAsyncSequential;
import static net.pincette.rs.Filter.filter;
import static net.pincette.rs.Mapper.map;
import static net.pincette.rs.Pipe.pipe;
import static net.pincette.rs.Util.pull;
import static net.pincette.rs.Util.tap;
import static net.pincette.util.Util.must;

import java.time.Instant;
import java.util.Optional;
import java.util.concurrent.Flow.Processor;
import javax.json.JsonObject;
import javax.json.JsonValue;
import net.pincette.rs.streams.Message;

/**
 * The $probe operator.
 *
 * @author Werner Donné
 */
class Probe {
  private Probe() {}

  private static Processor, Boolean> probe(
      final String name, final String topic, final Context context) {
    final Running running = new Running();

    return pipe(map(
            (Message m) ->
                m.withValue(updateRunning(running, name).orElse(null))))
        .then(filter(m -> m.value != null))
        .then(mapAsyncSequential(m -> context.producer.apply(topic, m)));
  }

  static Processor, Message> stage(
      final JsonValue expression, final Context context) {
    must(isObject(expression));

    return tap(
        pull(
            probe(
                expression.asJsonObject().getString("name"),
                expression.asJsonObject().getString("topic"),
                context)));
  }

  private static JsonObject toJson(final Running running, final String name) {
    return createObjectBuilder()
        .add("name", name)
        .add("minute", running.minute.toString())
        .add("count", running.count)
        .build();
  }

  private static Optional updateRunning(final Running running, final String name) {
    final Instant now = now().truncatedTo(MINUTES);

    if (between(running.minute, now).getSeconds() > 59) {
      final JsonObject result = toJson(running, name);

      running.count = 0;
      running.minute = now;

      return Optional.of(result);
    }

    ++running.count;

    return empty();
  }

  private static class Running {
    private long count = 0;
    private Instant minute = now().truncatedTo(MINUTES);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy