Class LinkedIOSubchannel

All Implemented Interfaces:
Associator, Channel, Eligible, Subchannel, IOSubchannel

Provides an I/O subchannel that is linked to another I/O subchannel.

A typical use case for this class is a protocol converter.

Protocol converters receive events related to an I/O resource from upstream, and while processing them usually generate new events to other components downstream (and vice versa). The events received are associated with a particular resource by the subchannel that is used to relay them. The association with the resource must be maintained for the newly generated events as well. It is, however, not possible to use the same subchannel for receiving from upstream and sending downstream because it wouldn’t be possible to distinguish between e.g. an Input event from upstream to the converter and an Input event (conveying the converted data) from the converter to the downstream components.

Therefore, the converter must provide and manage independent subchannels for the data streams on its downstream side with a one-to-one relationship to the upstream subchannels. The LinkedIOSubchannel class simplifies this task. It provides a new subchannel with a reference to an existing subchannel. This makes it easy to find the upstream subchannel for a given downstream (LinkedIOSubchannel) when processing response events. For finding the downstream IOSubchannel for a given upstream connection, instances associate themselves with the upstream channel using the converter component as key. This allows a subchannel to have several associated linked subchannels.

  • Constructor Details

    • LinkedIOSubchannel

      public LinkedIOSubchannel(Manager hub, Channel mainChannel, IOSubchannel upstreamChannel, EventPipeline responsePipeline)
      Creates a new LinkedIOSubchannel for a given main channel that links to the give I/O subchannel.

      Using this constructor is similar to invoking LinkedIOSubchannel(Manager, Channel, IOSubchannel, EventPipeline, boolean) with true as last parameter.

      Because the newly created LinkedIOSubchannel is referenced by the upstream channel, it will life as long as the upstream channel, even if no further references exist.

      Parameters:
      hub - the component that manages this channel
      mainChannel - the main channel
      upstreamChannel - the upstream channel
      responsePipeline - the response pipeline
    • LinkedIOSubchannel

      public LinkedIOSubchannel(Manager hub, Channel mainChannel, IOSubchannel upstreamChannel, EventPipeline responsePipeline, boolean linkBack)
      Creates a new LinkedIOSubchannel for a given main channel that links to a given I/O subchannel.

      Using this constructor with false as last parameter prevents the addition of the back link from the upstream channel to the downstream channel (see downstreamChannel(Manager, IOSubchannel)). This can save some space if a converter component has some other means to maintain that information. Note that in this case a reference to the created LinkedIOSubchannel must be maintained, else it may be garbage collected.

      Parameters:
      hub - the converter component that manages this channel
      mainChannel - the main channel
      upstreamChannel - the upstream channel
      responsePipeline - the response pipeline
      linkBack - create the link from upstream to downstream
  • Method Details

    • unlink

      public void unlink(Manager hub)
      Removes the association between the upstream channel and this channel.

      Should only be called if this channel is no longer used.

      Parameters:
      hub - the converter component that manages this channel
    • hub

      public Manager hub()
      Returns the component that manages this channel.
      Returns:
      the component that manages this channel
    • upstreamChannel

      Returns the upstream channel.
      Returns:
      the upstream channel
    • associated

      public <V> Optional<V> associated(Object by, Class<V> type)
      Delegates the invocation to the upstream channel if no associated data is found for this channel.
      Specified by:
      associated in interface Associator
      Overrides:
      associated in class Subchannel.DefaultSubchannel
      Type Parameters:
      V - the value type
      Parameters:
      by - the associator
      type - the type
      Returns:
      the optional
    • upstreamToString

      public static String upstreamToString(Channel upstream)
      The toString() method of LinkedIOSubchannels shows the channel together with the upstream channel that it is linked to.

      If there are several levels of upstream links, this can become a very long sequence.

      This method creates the representation of the linked upstream channel (an arrow followed by the representation of the channel), but only up to one level. If more levels exist, it returns an arrow followed by an ellipses. This method is used by toString(). Other implementations of IOSubchannel should use this method in their Object.toString() method as well to keep the result consistent.

      Parameters:
      upstream - the upstream channel
      Returns:
      the string
    • toString

      public String toString()
      Overrides:
      toString in class Subchannel.DefaultSubchannel
    • downstreamChannel

      public static Optional<? extends LinkedIOSubchannel> downstreamChannel(Manager hub, IOSubchannel upstreamChannel)
      Returns the linked downstream channel that has been created for the given component and (upstream) subchannel.

      If more than one linked subchannel has been created for a given component and subchannel, the linked subchannel created last is returned.

      Parameters:
      hub - the component that manages this channel
      upstreamChannel - the (upstream) channel
      Returns:
      the linked downstream subchannel created for the given component and (upstream) subchannel if it exists
    • downstreamChannel

      public static <T extends LinkedIOSubchannel> Optional<T> downstreamChannel(Manager hub, IOSubchannel upstreamChannel, Class<T> clazz)
      Like downstreamChannel(Manager, IOSubchannel), but with the return value of the specified type.
      Type Parameters:
      T - the generic type
      Parameters:
      hub - the component that manages this channel
      upstreamChannel - the (upstream) channel
      clazz - the type of the returned value
      Returns:
      the linked downstream subchannel created for the given component and (upstream) subchannel if it exists