Package reactor.core

Interface Scannable

All Known Subinterfaces:
Sinks.Empty<T>, Sinks.Many<T>, Sinks.ManyWithUpstream<T>, Sinks.One<T>
All Known Implementing Classes:
DirectProcessor, EmitterProcessor, FluxOperator, FluxProcessor, MonoOperator, MonoProcessor, Operators.DeferredSubscription, Operators.MonoSubscriber, ReplayProcessor, SinkOneSerialized, UnicastProcessor
Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

@FunctionalInterface public interface Scannable
A Scannable component exposes state in a non strictly memory consistent way and results should be understood as best-effort hint of the underlying state. This is useful to retro-engineer a component graph such as a flux operator chain via Stream queries from actuals(), parents() and inners(). This allows for visiting patterns and possibly enable serviceability features.

Scannable is also a useful tool for the advanced user eager to learn which kind of state we usually manage in the package-scope schedulers or operators implementations.

Author:
Stephane Maldini
  • Field Details

    • OPERATOR_NAME_UNRELATED_WORDS_PATTERN

      static final Pattern OPERATOR_NAME_UNRELATED_WORDS_PATTERN
      The pattern for matching words unrelated to operator name. Used to strip an operator name of various prefixes and suffixes.
  • Method Details

    • from

      static Scannable from(@Nullable Object o)
      Attempt to cast the Object to a Scannable. Return Scannable.Attr.NULL_SCAN if the value is null, or Scannable.Attr.UNAVAILABLE_SCAN if the value is not a Scannable. Both are constant Scannable that return false on isScanAvailable().
      Parameters:
      o - a reference to cast
      Returns:
      the casted Scannable, or one of two default Scannable instances that aren't actually scannable (one for nulls, one for non-scannable references)
    • actuals

      default Stream<? extends Scannable> actuals()
      Return a Stream navigating the Subscriber chain (downward). The current Scannable is not included.
      Returns:
      a Stream navigating the Subscriber chain (downward, current Scannable not included).
    • inners

      default Stream<? extends Scannable> inners()
      Return a Stream of referenced inners (flatmap, multicast etc)
      Returns:
      a Stream of referenced inners (flatmap, multicast etc)
    • isScanAvailable

      default boolean isScanAvailable()
      Return true whether the component is available for scan(Attr) resolution.
      Returns:
      true whether the component is available for scan(Attr) resolution.
    • name

      default String name()
      Check this Scannable and its parents() for a user-defined name and return the first one that is reachable, or default to this Scannable stepName() if none.
      Returns:
      the name of the first parent that has one defined (including this scannable)
    • stepName

      default String stepName()
      Return a meaningful String representation of this Scannable in its chain of parents() and actuals().
    • steps

      default Stream<String> steps()
      List the step names in the chain of Scannable (including the current element), in their assembly order. This traverses the chain of Scannable both upstream (parents()) and downstream (actuals()).
      1. if the current Scannable is a Subscriber, the chain can reach down to the final subscriber, provided it is Scannable (eg. lambda subscriber)
      2. if it is an operator the chain can reach up to the source, if it is a Reactor source (that is Scannable).
      Returns:
      a Stream of stepName() for each discovered step in the Scannable chain
    • parents

      default Stream<? extends Scannable> parents()
      Return a Stream navigating the Subscription chain (upward). The current Scannable is not included.
      Returns:
      a Stream navigating the Subscription chain (upward, current Scannable not included).
    • scanUnsafe

      @Nullable Object scanUnsafe(Scannable.Attr key)
      This method is used internally by components to define their key-value mappings in a single place. Although it is ignoring the generic type of the Scannable.Attr key, implementors should take care to return values of the correct type, and return null if no specific value is available.

      For public consumption of attributes, prefer using scan(Attr), which will return a typed value and fall back to the key's default if the component didn't define any mapping.

      Parameters:
      key - a Scannable.Attr to resolve for the component.
      Returns:
      the value associated to the key for that specific component, or null if none.
    • scan

      default <T> @Nullable T scan(Scannable.Attr<T> key)
      Introspect a component's specific state attribute, returning an associated value specific to that component, or the default value associated with the key, or null if the attribute doesn't make sense for that particular component and has no sensible default.
      Parameters:
      key - a Scannable.Attr to resolve for the component.
      Returns:
      a value associated to the key or null if unmatched or unresolved
    • scanOrDefault

      default <T> T scanOrDefault(Scannable.Attr<T> key, T defaultValue)
      Introspect a component's specific state attribute. If there's no specific value in the component for that key, fall back to returning the provided non null default.
      Parameters:
      key - a Scannable.Attr to resolve for the component.
      defaultValue - a fallback value if key resolve to null
      Returns:
      a value associated to the key or the provided default if unmatched or unresolved
    • tags

      default Stream<Tuple2<String,String>> tags()
      Visit this Scannable and its parents(), starting by the furthest reachable parent, and return a Stream of the tags which includes duplicates and outputs tags in declaration order (grandparent tag(s) > parent tag(s) > current tag(s)).

      Tags can only be discovered until no parent can be inspected, which happens either when the source publisher has been reached or when a non-reactor intermediate operator is present in the parent chain (i.e. a stage that is not Scannable for Scannable.Attr.PARENT).

      Returns:
      the stream of tags for this Scannable and its reachable parents, including duplicates
      See Also:
    • tagsDeduplicated

      @Deprecated default Map<String,String> tagsDeduplicated()
      Deprecated.
      Micrometer APIs generally deduplicate tags and key-value pairs by default, so for related use cases prefer tags().
      Visit this Scannable and its parents(), starting by the furthest reachable parent, deduplicate tags that have a common key by favoring the value declared last (current tag(s) > parent tag(s) > grandparent tag(s)) and return a Map of the deduplicated tags. Note that while the values are the "latest", the key iteration order reflects the tags' declaration order.

      Tags can only be discovered until no parent can be inspected, which happens either when the source publisher has been reached or when a non-reactor intermediate operator is present in the parent chain (i.e. a stage that is not Scannable for Scannable.Attr.PARENT).

      Returns:
      a Map of deduplicated tags from this Scannable and its reachable parents
      See Also: