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

cloud.prefab.client.internal.ContextShapeAggregator Maven / Gradle / Ivy

Go to download

API Client for https://prefab.cloud: rate limits, feature flags and semaphores as a service

There is a newer version: 0.3.23
Show newest version
package cloud.prefab.client.internal;

import cloud.prefab.context.PrefabContext;
import cloud.prefab.context.PrefabContextSetReadable;
import cloud.prefab.domain.Prefab;
import com.google.common.annotations.VisibleForTesting;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.StreamSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Capture context "shape" and
 */
public class ContextShapeAggregator {

  private static final Logger LOG = LoggerFactory.getLogger(ContextShapeAggregator.class);

  private final ConcurrentHashMap> shapes;

  private final AtomicBoolean dirtyFlag = new AtomicBoolean(true);

  ContextShapeAggregator() {
    this.shapes = new ConcurrentHashMap<>();
  }

  void reportContextUsage(PrefabContextSetReadable prefabContextSetReadable) {
    Prefab.ContextShapes currentShapes = extractShapes(prefabContextSetReadable);
    for (Prefab.ContextShape contextShape : currentShapes.getShapesList()) {
      ConcurrentHashMap contextMap = shapes.computeIfAbsent(
        contextShape.getName(),
        key -> new ConcurrentHashMap<>()
      );
      contextShape
        .getFieldTypesMap()
        .forEach((key, value) -> {
          Integer oldValue = contextMap.put(key, value);
          if (!Objects.equals(oldValue, value)) {
            boolean dirtyFlagRaised = dirtyFlag.compareAndSet(false, true);
            if (dirtyFlagRaised && LOG.isTraceEnabled()) {
              LOG.trace(
                "dirty flag raised by context name: {} and property {}",
                contextShape.getName(),
                key
              );
            }
          }
        });
    }
  }

  Optional getShapesIfNewInfo() {
    if (dirtyFlag.get()) {
      return Optional.of(getShapes());
    }
    return Optional.empty();
  }

  Prefab.ContextShapes getShapes() {
    return buildProtoShapesFromShapeState();
  }

  @VisibleForTesting
  Prefab.ContextShapes buildProtoShapesFromShapeState() {
    Prefab.ContextShapes.Builder shapesBuilder = Prefab.ContextShapes.newBuilder();
    shapes.forEach((contextName, contextMap) -> {
      Prefab.ContextShape.Builder shapeBuilder = Prefab.ContextShape
        .newBuilder()
        .setName(contextName);
      shapeBuilder.putAllFieldTypes(contextMap);
      shapesBuilder.addShapes(shapeBuilder);
    });

    return shapesBuilder.build();
  }

  private Prefab.ContextShapes extractShapes(
    PrefabContextSetReadable prefabContextSetReadable
  ) {
    Prefab.ContextShapes.Builder shapesBuilder = Prefab.ContextShapes.newBuilder();
    StreamSupport
      .stream(prefabContextSetReadable.getContexts().spliterator(), false)
      .map(PrefabContext::getShape)
      .forEach(shapesBuilder::addShapes);
    return shapesBuilder.build();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy