Hi, 
this mail is crossposted to several mailing lists. I hope you all
can forgive me for this. I think that what I write here may be of
interest to several parties in the EJB and JMS open source communities,
you all belong to.

The rational behind this mail is to start a discussion about the so
called JMS Application Sever Facility API. According to my view this
JMS-ASF is needed to get EJB 2.0 and MessageDriven Beans up and
working. But since AFS is a little vague it might be good to coordinate
the interpretation and implementations of AFS support, to make
interoperatibility possible.

Ok. The background to my concerns is this. I need MessageDriven Beans (MDB),
and I want it in an open source EJB server. I therefore started
implementing support for this in Jboss. I quickly came to the
conclusion that JMS AFS was necesarry to make MDB - more about that
further down). I checked SpyderMQ, but I could not find any support for
AFS. I checked OpenJMS, and there it was. So I have worked against the
OpenJMS implementations. That worked fine for the simple test case.

But when I started trying to figure out a more general API against a
generic ASF (SeverSessionPool) I run into problem: The OpenJMS
implementation of the ASF is not good enough. The ServerSessionPool
and ServerSessin might be test implementation, that is not the
important part though, because how the specification is interpretaded
will also govern how core JMS provider parts are implemented - and
that in its turn will govern if it will be at possible at all to
implement a generic ServerSessionPool. That is, if my interpretation
of the ASF is correct - which of course is an open question.

But here it comes. 

The JMS ASF is defined to make it possible to handle incoming
messages concurrently in an application server. The reason behind ASF
is as I understand i two:

1. A session is single threaded. To have more thread handle incoming
   messages will require more sessions.

2. This might be ok to implement for Queues without a special API, but
   for Topics it won't work, since every session will get a copy of
   every message.

Here the ASF comes in. In AFS it is not a session who is the
connection to the JMS provider, but a ConnectionConsumer. It is up to
the JMS provider to construct the ConnectionConsumer so that it
receives all messages and then interact with a ServerSessionPool and a
ServerSession. It will feed messages as they arrive into this
potentially concurrent environment.

And here comes an important restriction: The ServerSessionPool and
ServerSession is an implementation that the application server
provider provides, without any prior knowledge of the underlying JMS
implemenentation.  And the JMS provider will have no knowledge of the
underlying implementation of the ServerSession part. The only
communication between them will go through the open API:s.

Unfortunately, the spec is not crystal clear on what demand that will
place on the implementations. We have to interpret it. If I am
correct, there is only one possible way to do this. And it will affect
how the JMS-provider will have to implement there ASF support, and how
the application server provider will have to implement its part.

Here comes the interpretation:

To set up an ASF driven message handling we would generally do this
(we make the example for a Topic).

// Get the TopicFactory, TopicConnection and Topic - this is standard
TopicConnectionFactory factory = ...
TopicConncetion con = ...
Topic topic = ...

We now have to setup a ServerSessionPool. But how should a reasonable
constructor look, apart for some pooling variable? We don't know. To
know this we will have to analyze what this black box will have to be
able to do.

ServerSessionPool pool = construct(????);


We then make a ConnectionConsumer.

ConnectionConsumer consumer = con.createConnectionConsumer(
topic,selector,pool, maxMessages);

Thats it, from now on it should all work. But hey, how? As we all see,
there are not sessions involved here.

Following the spec, the JMS provider will interact with the
ServerSession stuff in the following way:

When it want to send one ore more messages to the subscriber it gets a
ServerSession from the ServerSession pool. It only knows two things
about a ServerSession.

It can invoke start(), and the ServerSession will the run in a separate
thread and consume the messages. 

But how do it stuff messages inside the ServerSession? In can also get
a Session object from the ServerSession.

And here it gets interesting. Who is responsible for the
implementation of this Session? We could interpreted it in a way that
both parties could be responsible. The spec is however clear on this
point. The Session object returned from the ServerSession pool is
implemented by the JMS-provider:

"Since both the ConnectionConsumer and Session are implemented by the
same JMS provider, they can accomplish the load using a private
mechanism"

What does this imply, for both parties?

- The provider of the ServerSessionPool and ServerSession must have a
  way of getting a Session, and it may only use the JMS API for this.

  The only way it may do this is by creating a Session through the
  Connection, ie the ServerSessionPool will have to take a
  TopicConnection and a QueueConnection to be able to accomplish
  this. To be able to create a session it must know if they are to be
  transacted, and the ack mode. (It will typically also need a MessageListener).

  ServerSessionPool(TopicConnection con, boolean transacted, int ack,
                    MessageListener listener)

     //Creates session internally by     
     con.createSession(transacted, ack);

- If I understand it correctly, this will also mean that for the JMS
  provider a Session which is created through a Connection which is
  connected to a ConnectionConsumer must have special semantic. It
  must somehow mark the connection as to return sessions that handle
  the ASF stuff, or something like that.

- How is the masses passed from the Session to the MessageListener?

  If we ad the following from the spec we may draw a conclusion:

  "The JMS provider retains control of its messages until they are
  delivered to the MessageListener."


  In my world this means, that for each ServerSession in the pool the
  following will have to be done:

  Session ses = con.createSession(transacted, ack);
  ses.setMessageListener(listener);

  In the ServerSession run() method a thread will be started and the
  sessions run() method will be invoke.


The base-line is this. If this interpretation is correct, this is
basically the only logical way to implement ServerSessionPools and
ServerSessions, and JMS provider must implement their JMS part as to
support such a usage.

To sum it up:

Minimum API for a ServerSessionPoolFactory:

        createServerSessionPool((TopicConnection con, boolean
                transacted, int ack,MessageListener listener);

        createServerSessionPool((QueueConnection con, boolean
                transacted, int ack,MessageListener listener);


        getServerSession() {
           // pop from pool
           // ad a real Session - or have it added when inserted into
           //pool. eg
           servSess.addSess(con.createSession(transacted, ack));
                                                          
           // return it
        }

        In ServerSession start method (after invoke running in
        separate thread:

        session.run();


Was this only stating the obvious? If I have understood the
implementation of ServerSessionPool and ServerSession in OpenJMS, it
was not done in this way - and I think the way they have done it is -
if not wrong - not a very usable solution. 

Would it not be good if the open source implementations of JMS is done
in such a way that it is possible to write a generic implementation of
the ServerSession stuff?

Will it be possible to work against OpenJMS and SpyderMQ in the way
described above.

Or am I totally lost here?

//Peter

If someone could explain to me how transactions work in JMS that would
be great.
-- 
------------------------------------------------------------
Peter Antman             Technology in Media, Box 34105 100 26 Stockholm
Systems Architect        WWW: http://www.tim.se
Email: [EMAIL PROTECTED]  WWW: http://www.backsource.org
Phone: +46-(0)8-506 381 11 Mobile: 070-675 3942 
------------------------------------------------------------



--
--------------------------------------------------------------
To subscribe:        [EMAIL PROTECTED]
To unsubscribe:      [EMAIL PROTECTED]
Problems?:           [EMAIL PROTECTED]

Reply via email to