I like this a lot.

The directional terms are still a problem. "source/sink" clashes with
AMQP "source/target". "inTreatment/outTreatment" is confusing because
"treatment" covers message and link treatments, but they don't always
flow in the same direction. E.g.

    outTreatment: linkBalanced

"out" refers to *outbound* messages, but "linkBalanced" means balance
the *inbound* receiver link-open requests across external servers. This
made my head hurt.

I have been fiddling around trying to find something genuinely better
but not there yet. I've got a couple of thoughts but not concrete yet:

 - separate message and link treatments in "treatment". This is clearer
but redundant and multiplies the number of in/out settings.

 - if you need separate in/out treatments, split the waypoint into a
source/sink pair for the same address. That is less confusing because
the "half-route" only has one message flow direction so no need for
inFoo/outFoo. It makes the config a little more verbose but this is a
complex use case.

I prefer the second for clarity and future-proofing. It means we can
add future options that might be set differently for inbound/outbound
without multiplying inFoo/outFoo, inBar/outBar on the route.

On Wed, 2016-02-24 at 16:06 -0500, Ted Ross wrote:
> Ok, how about this?
> 
> For direct messaging between producers and consumers:
> 
> Direct multicast delivery (one copy to every subscriber to the
> address):
> 
>      route {
>          address: service.mcast
>          type: direct
>          treatment: multicast
>      }
> 
> 
> Direct delivery to only the closest (lowest cost) subscriber:
> 
>      route {
>          address: service.regional
>          type: direct
>          treatment: closest
>      }
> 
> 
> Direct delivery to one subscriber favoring subscribers that settle 
> deliveries more quickly.
> 
>      route {
>          address: service
>          type: direct
>          treatment: balanced
>      }
> 
> 
> For messaging involving a queue, topic, or other intermediate
> process. 
> In these cases, the remote container may be identified by container-
> id 
> or connection label (container-id shown in examples):
> 
> Link-routing to a queue:
> 
>      route {
>          address: my_queue
>          type: waypoint
>          treatment: linkBalanced
>          container: <broker-container-id>
>      }
> 
> 
> Link-routing only for enqueue:
> 
>      route {
>          address: my_queue
>          type: sink
>          treatment: linkBalanced
>          container: <broker-container-id>
>      }
> 
> 
> Link-routing only for dequeue:
> 
>      route {
>          address: my_queue
>          type: source
>          treatment: linkBalanced
>          container: <broker-container-id>
>      }
> 
> 
> Simple queue waypoint (treatment defaults to 'balanced'):
> 
>      route {
>          address: my_queue
>          type: waypoint
>          container: <broker-container-id>
>      }
> 
> 
> Simple topic waypoint that supports selectors:
> 
>      route {
>          address: my_topic
>          type: waypoint
>          inTreatment: multicast
>          outTreatment: linkBalanced
>          container: <broker-container-id>
>      }
> 
> 
> Distributed (sharded) queue waypoint:
> 
>      route {
>          address: my_queue
>          type: waypoint
>          container: <broker-1-container-id>
>      }
>      route {
>          address: my_queue
>          type: waypoint
>          container: <broker-2-container-id>
>      }
> 
> 
> Distributed (sharded) topic waypoint:
> 
>      route {
>          address: my_topic
>          type: waypoint
>          inTreatment: multicast
>          outTreatment: linkBalanced
>          container: <broker-1-container-id>
>      }
>      route {
>          address: my_topic
>          type: waypoint
>          inTreatment: multicast
>          outTreatment: linkBalanced
>          container: <broker-2-container-id>
>      }
> 
> 
> =====================================================================
> Syntax:
> 
> route: {
>      type: direct | source | sink | waypoint
>      address: (address or prefix)
>      treatment: multicast | closest | balanced | linkBalanced
>      connector: (label of a connection to/from a remote container)
>      container: (ID of a connected remote container)
>      inTreatment: (override treatment for inbound traffic)
>      outTreatment: (override treatment for outbound traffic)
>      inAddress: (override address for inbound traffic)
>      outAddress: (override address for outbound traffic)
> }
> 
> 
> Some notes:
> 
> - I don't care for the negative connotations of "detour" and prefer
>    "waypoint" for describing a thing you must go through on your way
> to
>    the final destination.
> - I've replaced "fanout" + "bias" with "treatment" to describe how
> the
>    router handles the forwarding of messages.  There is precedent for
>    the use of this term (hat tip to Andy Smith) in Cisco's router
>    documentation.
> - Link-routing is just another kind of treatment, like multicast or
>    closest-consumer.  This removes the need for the "mixed" route as
>    described by Gordon.  It also removes any distinction between a
>    waypoint and a link-route-destination as a link-route-destination
>    simply becomes a waypoint with linkBalanced treatment.
> - I'm avoiding Alan's distinction between direct and indirect routes
> by
>    noting that "direct" is the only direct option whereas the other
>    types are indirect.
> - The notion of "direction" is replaced by the "source" and "sink"
>    route types.
> 
> 
> -Ted
> 
> 
> 
> On 02/24/2016 09:18 AM, Alan Conway wrote:
> > Minor update attached - I included Gordon's point about indirect
> > routes
> > being able to use a listener to accept an incoming broker
> > connection as
> > well as a connector to make an outgoing one, the new part:
> > 
> > ----
> > Indirect routes can use incoming connections from the external
> > application by specifying a `listener` instead of a `connector` and
> > an
> > AMQP `container` name to identify the external application.
> > 
> >       indirectRoute {
> >           address: my_queue  # TODO address patterns.
> >           listener: secure_broker_listener
> >           container: "mybroker-container-id"
> >           mode="message"
> >       }
> > ----
> > 
> > Here's the full thing:
> > 
> > ===========
> > Terminology
> > ===========
> > 
> > AMQP messages are sent on *links*. A link that sends messages from
> > an
> > application to a dispatch router is a *sender*. A link that
> > receives
> > messages for an application from a dispatch router is a *receiver*.
> > 
> > Dispatch router configuration defines *routes*. A route has an
> > *address*. Addresses can be AMQP address strings or patterns (TODO)
> > 
> > Incoming client links (senders or receivers) are attached to the
> > route
> > with a matching address. If a sender link has no address, messages
> > are
> > routed individually using the *to* address. Receiver links with no
> > address are not allowed.
> > 
> > There are several types of route:
> > 
> > A *directRoute* accepts sender and receiver links and forwards
> > messages
> > from senders to receivers. This allows clients to communicate
> > directly
> > without the need for a broker.
> > 
> > Example: direct route "foo" with fanout (replaces fixedAddress)
> > 
> >      "directRoute": { "address": "foo",  "fanout": "multiple" }
> > 
> > An *indirectRoute* creates links to an external application (such
> > as a
> > broker) and forwards messages from senders to the application, and
> > messages from the application to receivers. There are two modes:
> > 
> >   - message routing: the route creates its own links to the
> > external
> > application, there is no relationship with the sender/receiver
> > links.
> >   - link routing: the route creates external links that correspond
> > exactly with sender/receiver links. It forwards all link
> > information
> > (name, flow control, properties etc.) to the external application.
> > 
> > Link routing preserves more AMQP context between the client and the
> > external application. Message routing offers more flexibility to
> > modify
> > the message flow e.g. to load balance messages over multiple
> > brokers.
> > 
> > An indirectRoute can initiate a connection to the external
> > application
> > or accept an incoming connection from it.
> > 
> > Example: broker integration with link routing (replaces
> > linkRoutePattern)
> > 
> >       indirectRoute {
> >           address: my_queue  # TODO address patterns.
> >           connector: my_broker
> >           mode="link"
> >       }
> > 
> > Example: broker integration with message routing (replaces simple
> > waypoint)
> > 
> >       indirectRoute {
> >           address: my_queue  # TODO address patterns.
> >           connector: my_broker
> >           mode="message"
> >       }
> > 
> > Indirect routes can use incoming connections from the external
> > application by specifying a `listener` instead of a `connector` and
> > an
> > AMQP `container` name to identify the external application.
> > 
> >       indirectRoute {
> >           address: my_queue  # TODO address patterns.
> >           listener: secure_broker_listener
> >           container: "mybroker-container-id"
> >           mode="message"
> >       }
> > 
> > For more complex cases routes can create links to other routes.
> > Routes
> > always allow internal links, but a route can be configured to allow
> > only senders, receivers, both or none from outside. An external
> > link is
> > attached to the route that has the right its address *and* allows
> > that
> > link type. A route with `"allow": "none"` is an internal routing
> > detail
> > and cannot be accessed directly by clients.
> > 
> > Example: waypoint chaining
> > 
> >       # Route for messages sent to my_queue, forward to broker1
> >       indirectRoute {
> >           address: my_queue
> >           allow: sender
> >           connector: broker1
> >           mode: message
> >       }
> > 
> >       # Internal route for messages coming back from broker1,
> > forward to
> > broker2
> >       indirectRoute {
> >           address: my_queue
> >           allow: none  # internal only
> >           connector: broker1
> >           internalSender: ["broker2"] # send to broker2
> >           mode: message
> >      }
> > 
> >       # Route messages through broker2 and then back to receivers.
> >       indirectRoute {
> >           internalAddress: "broker2"
> >           connector: broker2
> >           allow: receiver
> >           mode: message
> >       }
> > 
> > Example: message-routing with load balancing over two brokers.
> > 
> >       # Route for senders to my_queue.
> >       directRoute {
> >           address: my_queue
> >           allow: sender
> >           internalSenders: ["broker1_my_queue", "broker2_my_queue"]
> >           fanout: multiple
> >       }
> > 
> >       # Route for receivers from my_queue.
> >       directRoute {
> >           address: my_queue
> >           allow: receiver
> >           internalReceivers: ["broker1_my_queue",
> > "broker2_my_queue"]
> >       }
> > 
> >       # Internal route to broker1
> >       indirectRoute {
> >           internalAddress: broker1_my_queue
> >           allow: none
> >           connector: broker1
> >       }
> > 
> >       # Internal route to broker2
> >       indirectRoute {
> >           internalAddress: broker2_my_queue
> >           allow: none
> >           connector: broker2
> >       }
> > 
> > TODO:
> > 
> > - indirect route with multiple listeners/connectors with/without
> > container name giving multiple choices of external apps. Policy
> > controol: link routes can't fan-out but they can load balance.
> > - mix link & message routes: "tap" messages from a link route and
> > message route them.
> > - pattern matching
> > - internal address rewriting?
> > - multi-tennant
> > 
> > 
> > 
> > 
> > -----------------------------------------------------------------
> > ----
> > To unsubscribe, e-mail: [email protected]
> > For additional commands, e-mail: [email protected]
> > 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to