This page is still very much Work In Progress. It should be consider a draft.


Introduction

This page describes the design of a "Link Registry". This refers to "Links" as defined by the AMQP 1.0 specification.

There are a couple of situations in which the broker needs to quickly look up links.

For this and other purposes the creation of a "Link Registry" is proposed.

Terminology and Responsibilities

The following is all extracted from the AMQP 1.0 specification. Where they disagree the specification is obviously the authoritative source.

Link

Terminus (source or target)

Link Endpoints (sender or receiver)

Session Endpoint

Establishing, Resuming, Reattaching, and Recovering Links

 

Further Considerations

Thread Safety

The Link Registry will be used across multiple connections and thus has to be thread-safe!

Especially Link Stealing seems dangerous. When stealing Link "foo" the Attaching Link (on IO-Thread-A) will have to wait for the Detach of the previously Attached Link being sent and processed by the broker (on IO-Thread-B). If at the same time Link "bar" is stolen from IO-Thread-A by IO-Thread-B there could be a deadlock if we are not careful. (Potentially use ConfigThread as serialising/coordiantor? bottleneck?)

Input Validation

The Link Registry will use user supplied values (link names, container ids). This information can come from both the config and over the wire. We have to make sure we validate both.

Specification Compliance

There are a couple of related sections in the AMQP 1.0 specification that we have to adhere to:

Requirements

Remembering Remote Terminus

Do we have to persist the remote Terminus? In the normal broker operation this seems unnecessary but when thinking about Broker federation we might want to remember for example whether the remote Terminus is a Queue or a Topic to validate upon resuming the Link.

Personally, I (Lorenz) think this is not necessary but if possible we should keep the design flexible enough to allow for a future extension.

Storage

Design v1 (obsolete)

Brainstorming

Stpes

  1. Merge (Sending-/Receiving-)LinkEndpoint and (Sending-/Receiving-)Link; Remove LinkAttachment
  2. Create Terminus Interface with methods to associate/dissociate a LinkEndpoint and maintain delivery states
  3. Make Source and Target Derive from Terminus and move the (non-durable) delivery state bookkeeping from the LinkEndpoint to the Terminus
  4. Create class for the LinkRegistry.
    1. encapsulate remoteContainer in the registry
    2. values are Termini
  5. replace current Map<containerId, LinkRegistry> on VH with new LinkRegistry

 

In receiveAttach:

void receiveAttach(Attach attach) {
  source, target = getAddressSpace().getLinkRegistry().getSendingLink(getConnection().getLocalContainerId(),
                                                                      getConnection().getRemoteContainerId(),
                                                                      attach.getLinkName(),
                                                                      attach.getSource(),
                                                                      attach.getTarget());
  if (source == null) {
    establishLink(attach);
  } else {
    if (attach.getSource() == null) {
      recoverLink(attach, source, target);
    } else {
      if (source.getAssociatedLinkEndpoint() == null) {
        resumeLink(attach, source, target);
      } else {
        if (source.getAssociatedLinkEndpoint().getSession() != this) {
          stealLink(attach, source, target);
        } else {
          reattachLink(attach, source, target);
        }
      }
    }
  }
}
 

 

LinkRegistry API

Problems

 

Design v2 (obsolete)

Instead of a LinkRegistry we introduce a LinkManager with expanded responsibilities.

Link

The Link encapsulates the Source, Target, and LinkEndpoint and keeps a reference to the associated Session.

API

The send* methods will most likely end up calling the corresponding methods on the session to do some session specific housekeeping and the actual sending

LinkManager API

Problems

This design was abandond because it is further away from the spec. v3 tries to remedy this.

 

Design v3

As in the other designs the Terminus will hold persistent state (e.g., Map<delivery-tag, unsettled state>).

We should support a optional and configurable timeout for the Links. If the Links are not Attached for more than the timeout they should be removed from the LinkRegistry.

Also see attached IRC conversation between Rob and Lorenz, especially with regards to Link stealing.

LinkRegistry

The LinkRegistry is responsible for ensuring Link uniqueness and persistence.

API

Non-Public API

The LinkRegistry should make the following functionality available to the Link

Link

The Link encapsulates the Source, Target, and LinkEndpoint and no further state.

API

LinkEndpoint

The LinkEndpoint is the object that the session and the consumer interact with.

This will have session related state (e.g., Map<delivery-ids, unsettled delivery state>).

API