activemq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Allan Schrum (JIRA)" <>
Subject [jira] Commented: (AMQNET-26) Add failover:// to NMS client
Date Mon, 13 Oct 2008 17:33:52 GMT


Allan Schrum commented on AMQNET-26:

I wish to contribute towards the resolution of this issue. As such, I have been examining
the Java implementation with hopes to understand it sufficiently so that I can replicate the
functions in C#. Below are my comments as to the steps or actions required to fix this problem.
If others can comment or correct my comments, then we can get started on this. If others are
willing to help with the coding or testing, that would be great.

All that I state below is what I have gleaned from the Java code. There is some interpretation
of the code that may be in error. If so, then those with sufficient knowledge should correct
my interpretation.

A quick jump through the stack: We start with a connection factory derived from ActiveMQConnectionFactory()
(C# ConnectionFactory()). This connection factory returns an IConnection which, as part of
the process, creates an ITransport using a TransportFactory(). In Java, the resource information
allows for various implementations of ITransport which includes FailoverTransport(). Different
from C#, the Java implementation breaks out the logic for creating a transport so that it
can be overridden by subclasses if desired. Not sure if we need that or not.

In the TransportFactory, it all starts with the URI associated with the connection. The "failover:(URI1,
URI2, ..., URIn)" syntax is passed to the TransportFactory.connect() to create the associated
ITransport object. Looking at TransportFactory.connect() it uses findTransportFactory() to
determine which class to load based upon the location passed. The URI.getScheme() method returns
"failover" which is used to load the failover transport factory (
This is based upon the META-INF information which redirects "failover" to that class.

At this point we have a choice. We can allow for dynamic loading of classes (which can be
done - not too hard) allowing for a similar run-time loading of appropriate classes to support
various ITransport interface classes, or we can punt and do something easy for a compile-time
loading of classes. My simple vote is to do a compile-time reference to the class which we
can move to run-time loading at a future date. I have done run-time loading of classes, so
if desired I can explain how I did it, but do we want that level of complexity at this point?

Tabling that issue, the fundamental questions now reside around the differences between TransportFactory()
and FailoverTransportFactory(), followed by the differences between Transport() and FailoverTransport().

The Java version of TransportFactory includes support for composite connections. This is used
to support reliable and HA connections. Basically, composite connections represent a list
of URIs associated with a connection.

Most of the extended functionality of the transports is handled through subclassing. Want
a ITransport that does X, then create a new subclass of Transport() or something that implements
ITransport() and now you have a new feature X. However, there is a client-side and server-side
for feature X (e.g. SSL). For SSL support, the client must understand how to connect properly,
and the server needs to understand how to accept the connection properly. Thus  some of the
classes that support ITransport() also support TransportServer() which handles the server-side
of things (I think this is correct). Not all features require this to work properly. For instance,
the failover: capability is a client-only feature that does not require server-side coding.

If we are to round-out all the neat features of the Java-based interfaces to be supported
here with .NET, then we need to carefully support this dual concept of client- and server-side
coding for the features.

I think that is the level of complexity that is implied by all the features in the Java-based
code. Essentially it breaks down into two sets of supported interfaces (Transport and TransportServer)
which are required depending upon the specific feature. The rest of the feature code seems
to be dependent upon the features being implemented.

OK - so what does this mean for our implementation? I would suggest the following:

1.	We create a Failover directory for our files with an implied "Failover" namespace extension.
2.	Create a FailoverTransportFactory.cs and FailoverTransport.cs classes that will implement
our new features (details to follow soon).
3.	Explicitly reference this new namespace and based upon the schema passed either call TcpTransportFactory()
or FailoverTransportFactory(). Using this ITransportFactory create the appropriate ITransport
4.	As we add new features, we can then decide to continue with this explicit compile-time
structure of referencing the classes, or we can think about a run-time loading of classes.
But that is for the future.

The key feature of FailoverTransportFactory() and FailoverTransport() is the ability to parse
and handle multiple URIs. There is logic to randomly (or sequentially) try to connect to each
URI until success. If successful, then life is good. If there is a failure, then a try to
reconnect is possible as well as tries to connect to the other URIs specified. Of course,
each URI can have it own connection qualifiers so each needs to be handled independently.

At this point I will stop for comments. The details of how FailoverTransport() should be implemented
are mostly in the Java code, but of course, details vary for C#.

> Add failover:// to NMS client
> -----------------------------
>                 Key: AMQNET-26
>                 URL:
>             Project: ActiveMQ .Net
>          Issue Type: New Feature
>          Components: ActiveMQ Client
>            Reporter: Denis Abramov
>            Assignee: Jim Gomes
>            Priority: Critical
>             Fix For: 1.1
> Please add failover:// to C# NMS Client. I would add it but I don't know how to resume
a stream once it is broken.

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message